diff options
Diffstat (limited to 'src/namestore/plugin_rest_namestore.c')
-rw-r--r-- | src/namestore/plugin_rest_namestore.c | 1276 |
1 files changed, 551 insertions, 725 deletions
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index ec44046e0..f14707cce 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c | |||
@@ -11,15 +11,15 @@ | |||
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 namestore/plugin_rest_namestore.c | 21 | * @file namestore/plugin_rest_namestore.c |
21 | * @brief GNUnet Namestore REST plugin | 22 | * @brief GNUnet Namestore REST plugin |
22 | * | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "platform.h" | 25 | #include "platform.h" |
@@ -28,38 +28,45 @@ | |||
28 | #include "gnunet_namestore_service.h" | 28 | #include "gnunet_namestore_service.h" |
29 | #include "gnunet_identity_service.h" | 29 | #include "gnunet_identity_service.h" |
30 | #include "gnunet_rest_lib.h" | 30 | #include "gnunet_rest_lib.h" |
31 | #include "gnunet_jsonapi_lib.h" | 31 | #include "gnunet_json_lib.h" |
32 | #include "gnunet_jsonapi_util.h" | ||
33 | #include "microhttpd.h" | 32 | #include "microhttpd.h" |
34 | #include <jansson.h> | 33 | #include <jansson.h> |
35 | 34 | ||
36 | #define GNUNET_REST_API_NS_NAMESTORE "/names" | ||
37 | |||
38 | #define GNUNET_REST_API_NS_NAMESTORE_ZKEY "/names/zkey" | ||
39 | |||
40 | #define GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO "record" | ||
41 | |||
42 | #define GNUNET_REST_JSONAPI_NAMESTORE_NAME "name" | ||
43 | |||
44 | #define GNUNET_REST_JSONAPI_NAMESTORE_REVINFO "revinfo" | ||
45 | 35 | ||
46 | #define GNUNET_REST_JSONAPI_NAMESTORE_RECORD GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO | 36 | #define GNUNET_REST_API_NS_NAMESTORE "/namestore" |
37 | #define GNUNET_REST_SUBSYSTEM_NAMESTORE "namestore" | ||
47 | 38 | ||
48 | #define GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE "record_type" | 39 | /** |
49 | 40 | * Parameter names | |
50 | #define GNUNET_REST_JSONAPI_NAMESTORE_VALUE "value" | 41 | */ |
51 | 42 | #define GNUNET_REST_API_PARAM_PUBKEY "pubkey" | |
52 | #define GNUNET_REST_JSONAPI_NAMESTORE_PUBLIC "public" | 43 | #define GNUNET_REST_API_PARAM_NAME "name" |
53 | 44 | ||
54 | #define GNUNET_REST_JSONAPI_NAMESTORE_SHADOW "shadow" | 45 | /** |
46 | * Error messages | ||
47 | */ | ||
48 | #define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error" | ||
55 | 49 | ||
56 | #define GNUNET_REST_JSONAPI_NAMESTORE_PKEY "pkey" | 50 | #define GNUNET_REST_NAMESTORE_RD_COUNT 1 |
57 | 51 | ||
58 | #define GNUNET_REST_JSONAPI_NAMESTORE_ZKEY "zkey" | 52 | /** |
53 | * State while collecting all egos | ||
54 | */ | ||
55 | #define ID_REST_STATE_INIT 0 | ||
59 | 56 | ||
60 | #define GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION "expiration" | 57 | /** |
58 | * Done collecting egos | ||
59 | */ | ||
60 | #define ID_REST_STATE_POST_INIT 1 | ||
61 | /** | ||
62 | * The configuration handle | ||
63 | */ | ||
64 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
61 | 65 | ||
62 | #define GNUNET_REST_JSONAPI_NAMESTORE_EGO "ego" | 66 | /** |
67 | * HTTP methods allows for this plugin | ||
68 | */ | ||
69 | static char* allow_methods; | ||
63 | 70 | ||
64 | /** | 71 | /** |
65 | * @brief struct returned by the initialization function of the plugin | 72 | * @brief struct returned by the initialization function of the plugin |
@@ -69,135 +76,110 @@ struct Plugin | |||
69 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 76 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
70 | }; | 77 | }; |
71 | 78 | ||
72 | |||
73 | /** | 79 | /** |
74 | * HTTP methods allows for this plugin | 80 | * The default namestore ego |
75 | */ | 81 | */ |
76 | static char* allow_methods; | 82 | struct EgoEntry |
77 | |||
78 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
79 | |||
80 | struct RecordEntry | ||
81 | { | 83 | { |
82 | /** | 84 | /** |
83 | * DLL | 85 | * DLL |
84 | */ | 86 | */ |
85 | struct RecordEntry *next; | 87 | struct EgoEntry *next; |
86 | 88 | ||
87 | /** | 89 | /** |
88 | * DLL | 90 | * DLL |
89 | */ | 91 | */ |
90 | struct RecordEntry *prev; | 92 | struct EgoEntry *prev; |
91 | |||
92 | }; | ||
93 | |||
94 | struct RequestHandle | ||
95 | { | ||
96 | /** | ||
97 | * Ego list | ||
98 | */ | ||
99 | struct RecordEntry *record_head; | ||
100 | |||
101 | /** | ||
102 | * Ego list | ||
103 | */ | ||
104 | struct record_entry *record_tail; | ||
105 | 93 | ||
106 | /** | 94 | /** |
107 | * JSON response object | 95 | * Ego Identifier |
108 | */ | 96 | */ |
109 | struct GNUNET_JSONAPI_Document *resp_object; | 97 | char *identifier; |
110 | 98 | ||
111 | /** | 99 | /** |
112 | * Rest connection | 100 | * Public key string |
113 | */ | 101 | */ |
114 | struct GNUNET_REST_RequestHandle *rest_handle; | 102 | char *keystring; |
115 | 103 | ||
116 | /** | 104 | /** |
117 | * Handle to GNS service. | 105 | * The Ego |
118 | */ | ||
119 | struct GNUNET_IDENTITY_Handle *identity_handle; | ||
120 | |||
121 | /** | ||
122 | * Handle to NAMESTORE | ||
123 | */ | 106 | */ |
124 | struct GNUNET_NAMESTORE_Handle *ns_handle; | 107 | struct GNUNET_IDENTITY_Ego *ego; |
108 | }; | ||
125 | 109 | ||
126 | /** | ||
127 | * Handle to NAMESTORE it | ||
128 | */ | ||
129 | struct GNUNET_NAMESTORE_ZoneIterator *list_it; | ||
130 | 110 | ||
111 | struct RequestHandle | ||
112 | { | ||
131 | /** | 113 | /** |
132 | * Private key for the zone | 114 | * Records to store |
133 | */ | 115 | */ |
134 | struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey; | 116 | char *label_name; |
135 | 117 | ||
136 | /** | 118 | /** |
137 | * Handle to identity lookup | 119 | * Records to store |
138 | */ | 120 | */ |
139 | struct GNUNET_IDENTITY_EgoLookup *ego_lookup; | 121 | struct GNUNET_GNSRECORD_Data *rd; |
140 | 122 | ||
141 | /** | 123 | /** |
142 | * Default Ego operation | 124 | * NAMESTORE Operation |
143 | */ | 125 | */ |
144 | struct GNUNET_IDENTITY_Operation *get_default; | 126 | struct GNUNET_NAMESTORE_QueueEntry *add_qe; |
145 | 127 | ||
146 | /** | 128 | /** |
147 | * Name of the ego | 129 | * Response object |
148 | */ | 130 | */ |
149 | char *ego_name; | 131 | json_t *resp_object; |
150 | 132 | ||
151 | /** | 133 | /** |
152 | * Record is public | 134 | * The processing state |
153 | */ | 135 | */ |
154 | int is_public; | 136 | int state; |
155 | 137 | ||
156 | /** | 138 | /** |
157 | * Shadow record | 139 | * Handle to NAMESTORE |
158 | */ | 140 | */ |
159 | int is_shadow; | 141 | struct GNUNET_NAMESTORE_Handle *ns_handle; |
160 | 142 | ||
161 | /** | 143 | /** |
162 | * Name of the record to modify | 144 | * Handle to NAMESTORE it |
163 | */ | 145 | */ |
164 | char *name; | 146 | struct GNUNET_NAMESTORE_ZoneIterator *list_it; |
165 | 147 | ||
166 | /** | 148 | /** |
167 | * Value of the record | 149 | * Private key for the zone |
168 | */ | 150 | */ |
169 | char *value; | 151 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey; |
170 | 152 | ||
171 | /** | 153 | /** |
172 | * Zkey string | 154 | * IDENTITY Operation |
173 | */ | 155 | */ |
174 | const char* zkey_str; | 156 | struct EgoEntry *ego_entry; |
175 | 157 | ||
176 | /** | 158 | /** |
177 | * record type | 159 | * Ego list |
178 | */ | 160 | */ |
179 | uint32_t type; | 161 | struct EgoEntry *ego_head; |
180 | 162 | ||
181 | /** | 163 | /** |
182 | * Records to store | 164 | * Ego list |
183 | */ | 165 | */ |
184 | struct GNUNET_GNSRECORD_Data *rd; | 166 | struct EgoEntry *ego_tail; |
185 | 167 | ||
186 | /** | 168 | /** |
187 | * record count | 169 | * IDENTITY Operation |
188 | */ | 170 | */ |
189 | unsigned int rd_count; | 171 | struct GNUNET_IDENTITY_Operation *op; |
190 | 172 | ||
191 | /** | 173 | /** |
192 | * NAMESTORE Operation | 174 | * Handle to Identity service. |
193 | */ | 175 | */ |
194 | struct GNUNET_NAMESTORE_QueueEntry *add_qe; | 176 | struct GNUNET_IDENTITY_Handle *identity_handle; |
195 | 177 | ||
196 | /** | 178 | /** |
197 | * NAMESTORE Operation | 179 | * Rest connection |
198 | */ | 180 | */ |
199 | struct GNUNET_NAMESTORE_QueueEntry *reverse_qe; | 181 | struct GNUNET_REST_RequestHandle *rest_handle; |
200 | 182 | ||
201 | /** | 183 | /** |
202 | * Desired timeout for the lookup (default is no timeout). | 184 | * Desired timeout for the lookup (default is no timeout). |
203 | */ | 185 | */ |
@@ -206,7 +188,7 @@ struct RequestHandle | |||
206 | /** | 188 | /** |
207 | * ID of a task associated with the resolution process. | 189 | * ID of a task associated with the resolution process. |
208 | */ | 190 | */ |
209 | struct GNUNET_SCHEDULER_Task * timeout_task; | 191 | struct GNUNET_SCHEDULER_Task *timeout_task; |
210 | 192 | ||
211 | /** | 193 | /** |
212 | * The plugin result processor | 194 | * The plugin result processor |
@@ -224,164 +206,201 @@ struct RequestHandle | |||
224 | char *url; | 206 | char *url; |
225 | 207 | ||
226 | /** | 208 | /** |
227 | * Cfg | 209 | * Error response message |
228 | */ | 210 | */ |
229 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 211 | char *emsg; |
230 | 212 | ||
231 | /** | 213 | /** |
232 | * HTTP response code | 214 | * Reponse code |
233 | */ | 215 | */ |
234 | int response_code; | 216 | int response_code; |
235 | 217 | ||
236 | }; | 218 | }; |
237 | 219 | ||
238 | |||
239 | /** | 220 | /** |
240 | * Cleanup lookup handle | 221 | * Cleanup lookup handle |
241 | * | ||
242 | * @param handle Handle to clean up | 222 | * @param handle Handle to clean up |
243 | */ | 223 | */ |
244 | static void | 224 | static void |
245 | cleanup_handle (struct RequestHandle *handle) | 225 | cleanup_handle (void *cls) |
246 | { | 226 | { |
247 | struct RecordEntry *record_entry; | 227 | struct RequestHandle *handle = cls; |
248 | struct RecordEntry *record_tmp; | 228 | struct EgoEntry *ego_entry; |
229 | struct EgoEntry *ego_tmp; | ||
249 | 230 | ||
250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 231 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
251 | "Cleaning up\n"); | 232 | "Cleaning up\n"); |
252 | if (NULL != handle->resp_object) | ||
253 | GNUNET_JSONAPI_document_delete (handle->resp_object); | ||
254 | if (NULL != handle->name) | ||
255 | GNUNET_free (handle->name); | ||
256 | if (NULL != handle->timeout_task) | 233 | if (NULL != handle->timeout_task) |
234 | { | ||
257 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | 235 | GNUNET_SCHEDULER_cancel (handle->timeout_task); |
258 | if (NULL != handle->ego_lookup) | 236 | handle->timeout_task = NULL; |
259 | GNUNET_IDENTITY_ego_lookup_cancel (handle->ego_lookup); | 237 | } |
260 | if (NULL != handle->get_default) | 238 | if (NULL != handle->label_name) |
261 | GNUNET_IDENTITY_cancel (handle->get_default); | 239 | GNUNET_free(handle->label_name); |
240 | if (NULL != handle->url) | ||
241 | GNUNET_free(handle->url); | ||
242 | if (NULL != handle->emsg) | ||
243 | GNUNET_free(handle->emsg); | ||
244 | if (NULL != handle->rd) | ||
245 | { | ||
246 | if (NULL != handle->rd->data) | ||
247 | GNUNET_free((void*)handle->rd->data); | ||
248 | GNUNET_free(handle->rd); | ||
249 | } | ||
250 | if (NULL != handle->timeout_task) | ||
251 | GNUNET_SCHEDULER_cancel(handle->timeout_task); | ||
262 | if (NULL != handle->list_it) | 252 | if (NULL != handle->list_it) |
263 | GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it); | 253 | GNUNET_NAMESTORE_zone_iteration_stop(handle->list_it); |
264 | if (NULL != handle->add_qe) | 254 | if (NULL != handle->add_qe) |
265 | GNUNET_NAMESTORE_cancel (handle->add_qe); | 255 | GNUNET_NAMESTORE_cancel(handle->add_qe); |
266 | if (NULL != handle->identity_handle) | 256 | if (NULL != handle->identity_handle) |
267 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | 257 | GNUNET_IDENTITY_disconnect(handle->identity_handle); |
268 | if (NULL != handle->ns_handle) | 258 | if (NULL != handle->ns_handle) |
269 | GNUNET_NAMESTORE_disconnect (handle->ns_handle); | ||
270 | if (NULL != handle->url) | ||
271 | GNUNET_free (handle->url); | ||
272 | if (NULL != handle->value) | ||
273 | GNUNET_free (handle->value); | ||
274 | if (NULL != handle->rd) | ||
275 | { | 259 | { |
276 | for (unsigned int i = 0; i < handle->rd_count; i++) | 260 | GNUNET_NAMESTORE_disconnect(handle->ns_handle); |
277 | { | ||
278 | if (NULL != handle->rd[i].data) | ||
279 | GNUNET_free ((void*)handle->rd[i].data); | ||
280 | } | ||
281 | GNUNET_free (handle->rd); | ||
282 | } | 261 | } |
283 | if (NULL != handle->ego_name) | 262 | |
284 | GNUNET_free (handle->ego_name); | 263 | for (ego_entry = handle->ego_head; |
285 | for (record_entry = handle->record_head; | 264 | NULL != ego_entry;) |
286 | NULL != record_entry;) | ||
287 | { | 265 | { |
288 | record_tmp = record_entry; | 266 | ego_tmp = ego_entry; |
289 | record_entry = record_entry->next; | 267 | ego_entry = ego_entry->next; |
290 | GNUNET_free (record_tmp); | 268 | GNUNET_free(ego_tmp->identifier); |
269 | GNUNET_free(ego_tmp->keystring); | ||
270 | GNUNET_free(ego_tmp); | ||
291 | } | 271 | } |
272 | |||
273 | if(NULL != handle->resp_object) | ||
274 | { | ||
275 | json_decref(handle->resp_object); | ||
276 | } | ||
277 | |||
292 | GNUNET_free (handle); | 278 | GNUNET_free (handle); |
293 | } | 279 | } |
294 | 280 | ||
295 | 281 | ||
296 | /** | 282 | /** |
297 | * Create json representation of a GNSRECORD | 283 | * Task run on errors. Reports an error and cleans up everything. |
298 | * | 284 | * |
299 | * @param rd the GNSRECORD_Data | 285 | * @param cls the `struct RequestHandle` |
300 | */ | 286 | */ |
301 | static json_t * | 287 | static void |
302 | gnsrecord_to_json (const struct GNUNET_GNSRECORD_Data *rd) | 288 | do_error (void *cls) |
303 | { | 289 | { |
304 | const char *typename; | 290 | struct RequestHandle *handle = cls; |
305 | char *string_val; | 291 | struct MHD_Response *resp; |
306 | const char *exp_str; | 292 | json_t *json_error = json_object(); |
307 | json_t *record_obj; | 293 | char *response; |
308 | 294 | ||
309 | typename = GNUNET_GNSRECORD_number_to_typename (rd->record_type); | 295 | if (NULL == handle->emsg) |
310 | string_val = GNUNET_GNSRECORD_value_to_string (rd->record_type, | 296 | handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_ERROR_UNKNOWN); |
311 | rd->data, | ||
312 | rd->data_size); | ||
313 | 297 | ||
314 | if (NULL == string_val) | 298 | json_object_set_new(json_error,"error", json_string(handle->emsg)); |
315 | { | 299 | |
316 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 300 | if (0 == handle->response_code) |
317 | "Record of type %d malformed, skipping\n", | 301 | handle->response_code = MHD_HTTP_OK; |
318 | (int) rd->record_type); | 302 | response = json_dumps (json_error, 0); |
319 | return NULL; | 303 | resp = GNUNET_REST_create_response (response); |
320 | } | 304 | handle->proc (handle->proc_cls, resp, handle->response_code); |
321 | record_obj = json_object(); | 305 | json_decref(json_error); |
322 | json_object_set_new (record_obj, | 306 | GNUNET_free(response); |
323 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE, | 307 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
324 | json_string (typename)); | 308 | } |
325 | json_object_set_new (record_obj, | 309 | |
326 | GNUNET_REST_JSONAPI_NAMESTORE_VALUE, | 310 | |
327 | json_string (string_val)); | 311 | /** |
328 | GNUNET_free (string_val); | 312 | * Get EgoEntry from list with either a public key or a name |
329 | 313 | * If public key and name are not NULL, it returns the public key result first | |
330 | if (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION & rd->flags) | 314 | * |
315 | * @param handle the RequestHandle | ||
316 | * @param pubkey the public key of an identity (only one can be NULL) | ||
317 | * @param name the name of an identity (only one can be NULL) | ||
318 | * @return EgoEntry or NULL if not found | ||
319 | */ | ||
320 | struct EgoEntry* | ||
321 | get_egoentry(struct RequestHandle *handle, char* pubkey, char *name) | ||
322 | { | ||
323 | struct EgoEntry *ego_entry; | ||
324 | if (NULL != pubkey) | ||
331 | { | 325 | { |
332 | struct GNUNET_TIME_Relative time_rel; | 326 | for (ego_entry = handle->ego_head; |
333 | time_rel.rel_value_us = rd->expiration_time; | 327 | NULL != ego_entry; |
334 | exp_str = GNUNET_STRINGS_relative_time_to_string (time_rel, 1); | 328 | ego_entry = ego_entry->next) |
329 | { | ||
330 | if (0 != strcasecmp (pubkey, ego_entry->keystring)) | ||
331 | continue; | ||
332 | return ego_entry; | ||
333 | } | ||
335 | } | 334 | } |
336 | else | 335 | if (NULL != name) |
337 | { | 336 | { |
338 | struct GNUNET_TIME_Absolute time_abs; | 337 | for (ego_entry = handle->ego_head; |
339 | time_abs.abs_value_us = rd->expiration_time; | 338 | NULL != ego_entry; |
340 | exp_str = GNUNET_STRINGS_absolute_time_to_string (time_abs); | 339 | ego_entry = ego_entry->next) |
340 | { | ||
341 | if (0 != strcasecmp (name, ego_entry->identifier)) | ||
342 | continue; | ||
343 | return ego_entry; | ||
344 | } | ||
341 | } | 345 | } |
342 | json_object_set_new (record_obj, GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION, json_string (exp_str)); | 346 | return NULL; |
343 | |||
344 | json_object_set_new (record_obj, "expired", | ||
345 | json_boolean (GNUNET_YES == GNUNET_GNSRECORD_is_expired (rd))); | ||
346 | return record_obj; | ||
347 | } | 347 | } |
348 | 348 | ||
349 | 349 | ||
350 | /** | 350 | /** |
351 | * Task run on error. Generates error response and cleans up. | 351 | * Does internal server error when iteration failed. |
352 | * | ||
353 | * @param cls the request to generate an error response for | ||
354 | */ | 352 | */ |
355 | static void | 353 | static void |
356 | do_error (void *cls) | 354 | namestore_iteration_error (void *cls) |
357 | { | 355 | { |
358 | struct RequestHandle *handle = cls; | 356 | struct RequestHandle *handle = cls; |
359 | struct MHD_Response *resp = GNUNET_REST_create_response (NULL); | 357 | struct MHD_Response *resp = GNUNET_REST_create_response (NULL); |
360 | 358 | handle->proc (handle->proc_cls, resp, MHD_HTTP_INTERNAL_SERVER_ERROR); | |
361 | handle->proc (handle->proc_cls, resp, handle->response_code); | 359 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
362 | cleanup_handle (handle); | ||
363 | } | 360 | } |
364 | 361 | ||
365 | 362 | ||
366 | /** | ||
367 | * Task run on timeout. | ||
368 | * | ||
369 | * @param cls the request to time out | ||
370 | */ | ||
371 | static void | 363 | static void |
372 | do_timeout (void *cls) | 364 | create_finished (void *cls, int32_t success, const char *emsg) |
373 | { | 365 | { |
374 | struct RequestHandle *handle = cls; | 366 | struct RequestHandle *handle = cls; |
367 | struct MHD_Response *resp; | ||
375 | 368 | ||
376 | handle->timeout_task = NULL; | 369 | handle->add_qe = NULL; |
377 | do_error (handle); | 370 | if (GNUNET_YES != success) |
371 | { | ||
372 | handle->emsg = GNUNET_strdup("Error storing records"); | ||
373 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
374 | return; | ||
375 | } | ||
376 | resp = GNUNET_REST_create_response (NULL); | ||
377 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT); | ||
378 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
378 | } | 379 | } |
379 | 380 | ||
380 | 381 | ||
381 | static void | 382 | static void |
382 | cleanup_handle_delayed (void *cls) | 383 | del_finished (void *cls, int32_t success, const char *emsg) |
383 | { | 384 | { |
384 | cleanup_handle (cls); | 385 | struct RequestHandle *handle = cls; |
386 | |||
387 | handle->add_qe = NULL; | ||
388 | if (GNUNET_NO == success) | ||
389 | { | ||
390 | handle->emsg = GNUNET_strdup("Deleting record failed. Record does not exist"); | ||
391 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
392 | return; | ||
393 | } | ||
394 | if (GNUNET_SYSERR == success) | ||
395 | { | ||
396 | handle->emsg = GNUNET_strdup("Deleting record failed"); | ||
397 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
398 | return; | ||
399 | } | ||
400 | handle->proc (handle->proc_cls, | ||
401 | GNUNET_REST_create_response (NULL), | ||
402 | MHD_HTTP_NO_CONTENT); | ||
403 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
385 | } | 404 | } |
386 | 405 | ||
387 | 406 | ||
@@ -395,31 +414,24 @@ static void | |||
395 | namestore_list_finished (void *cls) | 414 | namestore_list_finished (void *cls) |
396 | { | 415 | { |
397 | struct RequestHandle *handle = cls; | 416 | struct RequestHandle *handle = cls; |
398 | char *result; | 417 | char *result_str; |
399 | struct MHD_Response *resp; | 418 | struct MHD_Response *resp; |
400 | 419 | ||
401 | handle->list_it = NULL; | 420 | handle->list_it = NULL; |
402 | if (NULL == handle->resp_object) | ||
403 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
404 | 421 | ||
405 | if (GNUNET_SYSERR == | 422 | if (NULL == handle->resp_object) |
406 | GNUNET_JSONAPI_document_serialize (handle->resp_object, | ||
407 | &result)) | ||
408 | { | 423 | { |
409 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 424 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
410 | GNUNET_SCHEDULER_add_now (&do_error, | ||
411 | handle); | ||
412 | return; | 425 | return; |
413 | } | 426 | } |
414 | resp = GNUNET_REST_create_response (result); | ||
415 | handle->proc (handle->proc_cls, | ||
416 | resp, | ||
417 | MHD_HTTP_OK); | ||
418 | GNUNET_free_non_null (result); | ||
419 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, | ||
420 | handle); | ||
421 | } | ||
422 | 427 | ||
428 | result_str = json_dumps (handle->resp_object, 0); | ||
429 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | ||
430 | resp = GNUNET_REST_create_response (result_str); | ||
431 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
432 | GNUNET_free_non_null (result_str); | ||
433 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
434 | } | ||
423 | 435 | ||
424 | 436 | ||
425 | /** | 437 | /** |
@@ -428,84 +440,111 @@ namestore_list_finished (void *cls) | |||
428 | * @param handle the RequestHandle | 440 | * @param handle the RequestHandle |
429 | */ | 441 | */ |
430 | static void | 442 | static void |
431 | namestore_list_response (void *cls, | 443 | namestore_list_iteration (void *cls, |
432 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, | 444 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, |
433 | const char *rname, | 445 | const char *rname, |
434 | unsigned int rd_len, | 446 | unsigned int rd_len, |
435 | const struct GNUNET_GNSRECORD_Data *rd) | 447 | const struct GNUNET_GNSRECORD_Data *rd) |
436 | { | 448 | { |
437 | struct RequestHandle *handle = cls; | 449 | struct RequestHandle *handle = cls; |
438 | struct GNUNET_JSONAPI_Resource *json_resource; | ||
439 | json_t *result_array; | ||
440 | json_t *record_obj; | 450 | json_t *record_obj; |
441 | 451 | ||
442 | if (NULL == handle->resp_object) | 452 | if (NULL == handle->resp_object) |
443 | handle->resp_object = GNUNET_JSONAPI_document_new (); | 453 | handle->resp_object = json_array(); |
444 | 454 | ||
445 | if ( (NULL != handle->name) && | 455 | /*if ( (NULL != handle->ego_entry->identifier) && |
446 | (0 != strcmp (handle->name, | 456 | (0 != strcmp (handle->ego_entry->identifier, |
447 | rname)) ) | 457 | rname)) ) |
448 | { | 458 | { |
449 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 459 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
450 | "%s does not match %s\n", | 460 | "%s does not match %s\n", rname, |
451 | rname, | 461 | handle->ego_entry->identifier); |
452 | handle->name); | 462 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1); |
453 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, | ||
454 | 1); | ||
455 | return; | 463 | return; |
456 | } | 464 | }*/ |
457 | 465 | ||
458 | result_array = json_array (); | 466 | for (unsigned int i = 0; i < rd_len; i++) |
459 | for (unsigned int i=0; i<rd_len; i++) | ||
460 | { | 467 | { |
461 | if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && | 468 | if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && |
462 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)) ) | 469 | (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)) ) |
463 | continue; | 470 | continue; |
464 | 471 | ||
465 | if ( (rd[i].record_type != handle->type) && | 472 | record_obj = GNUNET_JSON_from_gns_record(rname,rd); |
466 | (GNUNET_GNSRECORD_TYPE_ANY != handle->type) ) | 473 | |
474 | if(NULL == record_obj) | ||
467 | continue; | 475 | continue; |
468 | record_obj = gnsrecord_to_json (&rd[i]); | ||
469 | json_array_append (result_array, | ||
470 | record_obj); | ||
471 | json_decref (record_obj); | ||
472 | } | ||
473 | 476 | ||
474 | if (0 < json_array_size(result_array)) | 477 | json_array_append (handle->resp_object, record_obj); |
475 | { | 478 | json_decref (record_obj); |
476 | json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_NAMESTORE_TYPEINFO, | ||
477 | rname); | ||
478 | GNUNET_JSONAPI_resource_add_attr (json_resource, | ||
479 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD, | ||
480 | result_array); | ||
481 | GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); | ||
482 | } | 479 | } |
483 | 480 | ||
484 | json_decref (result_array); | 481 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, 1); |
485 | GNUNET_NAMESTORE_zone_iterator_next (handle->list_it, | ||
486 | 1); | ||
487 | } | 482 | } |
488 | 483 | ||
489 | 484 | ||
490 | static void | 485 | /** |
491 | create_finished (void *cls, int32_t success, const char *emsg) | 486 | * Handle namestore GET request |
487 | * | ||
488 | * @param con_handle the connection handle | ||
489 | * @param url the url | ||
490 | * @param cls the RequestHandle | ||
491 | */ | ||
492 | void | ||
493 | namestore_get (struct GNUNET_REST_RequestHandle *con_handle, | ||
494 | const char* url, | ||
495 | void *cls) | ||
492 | { | 496 | { |
493 | struct RequestHandle *handle = cls; | 497 | struct RequestHandle *handle = cls; |
494 | struct MHD_Response *resp; | 498 | struct EgoEntry *ego_entry = NULL; |
499 | struct GNUNET_HashCode key; | ||
500 | char *pubkey = NULL; | ||
501 | char *name = NULL; | ||
502 | |||
503 | //change zone if pubkey or name specified | ||
504 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY, | ||
505 | strlen (GNUNET_REST_API_PARAM_PUBKEY), | ||
506 | &key); | ||
507 | if ( GNUNET_YES | ||
508 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
509 | &key)) | ||
510 | { | ||
511 | pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, | ||
512 | &key); | ||
513 | } | ||
514 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME, | ||
515 | strlen (GNUNET_REST_API_PARAM_NAME), | ||
516 | &key); | ||
517 | if ( GNUNET_YES | ||
518 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
519 | &key)) | ||
520 | { | ||
521 | name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, | ||
522 | &key); | ||
523 | } | ||
495 | 524 | ||
496 | handle->add_qe = NULL; | 525 | ego_entry = get_egoentry(handle,pubkey,name); |
497 | if (GNUNET_YES != success) | 526 | if (NULL == ego_entry) |
498 | { | 527 | { |
499 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 528 | if (NULL != pubkey || NULL != name) |
500 | "Error storing records%s%s\n", | 529 | { |
501 | (NULL == emsg) ? "" : ": ", | 530 | handle->emsg = GNUNET_strdup("Invalid identity"); |
502 | (NULL == emsg) ? "" : emsg); | 531 | handle->response_code = MHD_HTTP_NOT_FOUND; |
503 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 532 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
504 | return; | 533 | return; |
534 | } | ||
505 | } | 535 | } |
506 | resp = GNUNET_REST_create_response (NULL); | 536 | if ( NULL != ego_entry ) |
507 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT); | 537 | { |
508 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 538 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); |
539 | } | ||
540 | handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | ||
541 | handle->zone_pkey, | ||
542 | &namestore_iteration_error, | ||
543 | handle, | ||
544 | &namestore_list_iteration, | ||
545 | handle, | ||
546 | &namestore_list_finished, | ||
547 | handle); | ||
509 | } | 548 | } |
510 | 549 | ||
511 | 550 | ||
@@ -529,10 +568,10 @@ create_new_record_cont (void *cls, | |||
529 | struct RequestHandle *handle = cls; | 568 | struct RequestHandle *handle = cls; |
530 | 569 | ||
531 | handle->add_qe = NULL; | 570 | handle->add_qe = NULL; |
532 | if (0 != strcmp (rec_name, handle->name)) | 571 | if (0 != strcmp (rec_name, handle->label_name)) |
533 | { | 572 | { |
534 | GNUNET_break (0); | 573 | GNUNET_break (0); |
535 | do_error (handle); | 574 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
536 | return; | 575 | return; |
537 | } | 576 | } |
538 | 577 | ||
@@ -541,426 +580,262 @@ create_new_record_cont (void *cls, | |||
541 | handle->proc (handle->proc_cls, | 580 | handle->proc (handle->proc_cls, |
542 | GNUNET_REST_create_response (NULL), | 581 | GNUNET_REST_create_response (NULL), |
543 | MHD_HTTP_CONFLICT); | 582 | MHD_HTTP_CONFLICT); |
544 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 583 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
545 | return; | 584 | return; |
546 | } | 585 | } |
547 | |||
548 | GNUNET_assert (NULL != handle->name); | ||
549 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | 586 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, |
550 | &handle->zone_pkey, | 587 | handle->zone_pkey, |
551 | handle->name, | 588 | handle->label_name, |
552 | handle->rd_count, | 589 | GNUNET_REST_NAMESTORE_RD_COUNT, |
553 | handle->rd, | 590 | handle->rd, |
554 | &create_finished, | 591 | &create_finished, |
555 | handle); | 592 | handle); |
556 | } | 593 | } |
557 | 594 | ||
558 | 595 | /** | |
559 | static void | 596 | * Handle namestore POST request |
560 | del_finished (void *cls, | 597 | * |
561 | int32_t success, | 598 | * @param con_handle the connection handle |
562 | const char *emsg) | 599 | * @param url the url |
600 | * @param cls the RequestHandle | ||
601 | */ | ||
602 | void | ||
603 | namestore_add (struct GNUNET_REST_RequestHandle *con_handle, | ||
604 | const char* url, | ||
605 | void *cls) | ||
563 | { | 606 | { |
564 | struct RequestHandle *handle = cls; | 607 | struct RequestHandle *handle = cls; |
608 | struct GNUNET_GNSRECORD_Data *gns_record; | ||
609 | json_t *data_js; | ||
610 | json_t *name_json; | ||
611 | json_error_t err; | ||
565 | 612 | ||
566 | handle->add_qe = NULL; | 613 | struct EgoEntry *ego_entry = NULL; |
567 | if (GNUNET_NO == success) | 614 | struct GNUNET_HashCode key; |
615 | char *pubkey = NULL; | ||
616 | char *name = NULL; | ||
617 | |||
618 | char term_data[handle->rest_handle->data_size + 1]; | ||
619 | struct GNUNET_JSON_Specification gnsspec[] = { | ||
620 | GNUNET_JSON_spec_gnsrecord_data(&gns_record), | ||
621 | GNUNET_JSON_spec_end () | ||
622 | }; | ||
623 | |||
624 | if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url)) | ||
568 | { | 625 | { |
569 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 626 | handle->emsg = GNUNET_strdup("Wrong URL"); |
570 | _("Deleting record failed, record does not exist%s%s\n"), | 627 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
571 | (NULL != emsg) ? ": " : "", | ||
572 | (NULL != emsg) ? emsg : ""); | ||
573 | GNUNET_SCHEDULER_add_now (&do_error, handle); //do_not_found TODO | ||
574 | return; | 628 | return; |
575 | } | 629 | } |
576 | if (GNUNET_SYSERR == success) | 630 | if (0 >= handle->rest_handle->data_size) |
577 | { | 631 | { |
578 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 632 | handle->emsg = GNUNET_strdup("No data"); |
579 | _("Deleting record failed%s%s\n"), | ||
580 | (NULL != emsg) ? ": " : "", | ||
581 | (NULL != emsg) ? emsg : ""); | ||
582 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 633 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
583 | return; | 634 | return; |
584 | } | 635 | } |
585 | handle->proc (handle->proc_cls, | 636 | term_data[handle->rest_handle->data_size] = '\0'; |
586 | GNUNET_REST_create_response (NULL), | 637 | GNUNET_memcpy(term_data, handle->rest_handle->data, |
587 | MHD_HTTP_NO_CONTENT); | 638 | handle->rest_handle->data_size); |
588 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 639 | data_js = json_loads (term_data, JSON_DECODE_ANY, &err); |
589 | } | 640 | if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)) |
590 | |||
591 | |||
592 | static void | ||
593 | del_cont (void *cls, | ||
594 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | ||
595 | const char *label, | ||
596 | unsigned int rd_count, | ||
597 | const struct GNUNET_GNSRECORD_Data *rd) | ||
598 | { | ||
599 | struct RequestHandle *handle = cls; | ||
600 | |||
601 | handle->add_qe = NULL; | ||
602 | if (0 == rd_count) | ||
603 | { | 641 | { |
604 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 642 | handle->emsg = GNUNET_strdup("Invalid data"); |
605 | _("There are no records under label `%s' that could be deleted.\n"), | 643 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
606 | label); | 644 | GNUNET_JSON_parse_free(gnsspec); |
607 | do_error (handle); | 645 | json_decref (data_js); |
608 | return; | 646 | return; |
609 | } | 647 | } |
648 | handle->rd = gns_record; | ||
610 | 649 | ||
611 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | 650 | name_json = json_object_get(data_js, "label"); |
612 | &handle->zone_pkey, | 651 | if (!json_is_string(name_json)) |
613 | handle->name, | ||
614 | 0, NULL, | ||
615 | &del_finished, | ||
616 | handle); | ||
617 | } | ||
618 | |||
619 | |||
620 | static void | ||
621 | namestore_delete_cont (struct GNUNET_REST_RequestHandle *con, | ||
622 | const char *url, | ||
623 | void *cls) | ||
624 | { | ||
625 | struct RequestHandle *handle = cls; | ||
626 | |||
627 | if (NULL == handle->name) | ||
628 | { | 652 | { |
653 | handle->emsg = GNUNET_strdup("Missing name"); | ||
629 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 654 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
655 | json_decref (data_js); | ||
630 | return; | 656 | return; |
631 | } | 657 | } |
632 | 658 | handle->label_name = GNUNET_strdup(json_string_value(name_json)); | |
633 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, | 659 | if(NULL == handle->label_name) |
634 | &handle->zone_pkey, | ||
635 | handle->name, | ||
636 | &do_error, | ||
637 | handle, | ||
638 | &del_cont, | ||
639 | handle); | ||
640 | } | ||
641 | |||
642 | |||
643 | static int | ||
644 | json_to_gnsrecord (const json_t *records_json, | ||
645 | struct GNUNET_GNSRECORD_Data **rd, | ||
646 | unsigned int *rd_count) | ||
647 | { | ||
648 | struct GNUNET_TIME_Relative etime_rel; | ||
649 | struct GNUNET_TIME_Absolute etime_abs; | ||
650 | char *value; | ||
651 | void *rdata; | ||
652 | size_t rdata_size; | ||
653 | const char *typestring; | ||
654 | const char *expirationstring; | ||
655 | json_t *type_json; | ||
656 | json_t *value_json; | ||
657 | json_t *record_json; | ||
658 | json_t *exp_json; | ||
659 | |||
660 | *rd_count = json_array_size (records_json); | ||
661 | *rd = GNUNET_new_array (*rd_count, | ||
662 | struct GNUNET_GNSRECORD_Data); | ||
663 | for (unsigned int i = 0; i < *rd_count; i++) | ||
664 | { | 660 | { |
665 | memset (&(*rd)[i], | 661 | handle->emsg = GNUNET_strdup("Missing name"); |
666 | 0, | ||
667 | sizeof (struct GNUNET_GNSRECORD_Data)); | ||
668 | record_json = json_array_get (records_json, | ||
669 | i); | ||
670 | type_json = json_object_get (record_json, | ||
671 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE); | ||
672 | if (! json_is_string (type_json)) | ||
673 | { | ||
674 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
675 | "Type property is no string\n"); | ||
676 | return GNUNET_SYSERR; | ||
677 | } | ||
678 | typestring = json_string_value (type_json); | ||
679 | (*rd)[i].record_type = GNUNET_GNSRECORD_typename_to_number (typestring); | ||
680 | if (UINT32_MAX == (*rd)[i].record_type) | ||
681 | { | ||
682 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unsupported type `%s'\n"), | ||
683 | json_string_value (type_json)); | ||
684 | return GNUNET_SYSERR; | ||
685 | } | ||
686 | value_json = json_object_get (record_json, | ||
687 | GNUNET_REST_JSONAPI_NAMESTORE_VALUE); | ||
688 | if (! json_is_string (value_json)) | ||
689 | { | ||
690 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
691 | "Value property is no string\n"); | ||
692 | return GNUNET_SYSERR; | ||
693 | } | ||
694 | value = GNUNET_strdup (json_string_value (value_json)); | ||
695 | if (GNUNET_OK != | ||
696 | GNUNET_GNSRECORD_string_to_value ((*rd)[i].record_type, | ||
697 | value, | ||
698 | &rdata, | ||
699 | &rdata_size)) | ||
700 | { | ||
701 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
702 | _("Value `%s' invalid for record type `%s'\n"), | ||
703 | value, | ||
704 | typestring); | ||
705 | return GNUNET_SYSERR; | ||
706 | } | ||
707 | (*rd)[i].data = rdata; | ||
708 | (*rd)[i].data_size = rdata_size; | ||
709 | /**TODO | ||
710 | * if (1 == handle->is_shadow) | ||
711 | rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | ||
712 | if (1 != handle->is_public) | ||
713 | rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE; | ||
714 | */ | ||
715 | exp_json = json_object_get (record_json, | ||
716 | GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION); | ||
717 | if (! json_is_string (exp_json)) | ||
718 | { | ||
719 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
720 | "Expiration property is no string\n"); | ||
721 | return GNUNET_SYSERR; | ||
722 | } | ||
723 | expirationstring = json_string_value (exp_json); | ||
724 | if (0 == strcmp (expirationstring, "never")) | ||
725 | { | ||
726 | (*rd)[i].expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
727 | } | ||
728 | else if (GNUNET_OK == | ||
729 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, | ||
730 | &etime_rel)) | ||
731 | { | ||
732 | (*rd)[i].expiration_time = etime_rel.rel_value_us; | ||
733 | (*rd)[i].flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
734 | } | ||
735 | else if (GNUNET_OK == | ||
736 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, | ||
737 | &etime_abs)) | ||
738 | { | ||
739 | (*rd)[i].expiration_time = etime_abs.abs_value_us; | ||
740 | } | ||
741 | else | ||
742 | { | ||
743 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
744 | _("Value `%s' invalid for record type `%s'\n"), | ||
745 | value, | ||
746 | typestring); | ||
747 | return GNUNET_SYSERR; | ||
748 | } | ||
749 | } | ||
750 | return GNUNET_OK; | ||
751 | } | ||
752 | |||
753 | |||
754 | static void | ||
755 | namestore_create_cont (struct GNUNET_REST_RequestHandle *con, | ||
756 | const char *url, | ||
757 | void *cls) | ||
758 | { | ||
759 | struct RequestHandle *handle = cls; | ||
760 | struct MHD_Response *resp; | ||
761 | struct GNUNET_JSONAPI_Document *json_obj; | ||
762 | struct GNUNET_JSONAPI_Resource *json_res; | ||
763 | json_t *records_json; | ||
764 | json_t *data_js; | ||
765 | json_error_t err; | ||
766 | char term_data[handle->rest_handle->data_size+1]; | ||
767 | struct GNUNET_JSON_Specification docspec[] = { | ||
768 | GNUNET_JSON_spec_jsonapi_document (&json_obj), | ||
769 | GNUNET_JSON_spec_end() | ||
770 | }; | ||
771 | |||
772 | if (strlen (GNUNET_REST_API_NS_NAMESTORE) != strlen (handle->url)) | ||
773 | { | ||
774 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
775 | "Cannot create under %s\n", handle->url); | ||
776 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 662 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
663 | json_decref (data_js); | ||
777 | return; | 664 | return; |
778 | } | 665 | } |
779 | if (0 >= handle->rest_handle->data_size) | 666 | if (0 >= strlen(handle->label_name)) |
780 | { | 667 | { |
668 | handle->emsg = GNUNET_strdup("Missing name"); | ||
781 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 669 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
670 | json_decref (data_js); | ||
782 | return; | 671 | return; |
783 | } | 672 | } |
784 | term_data[handle->rest_handle->data_size] = '\0'; | ||
785 | GNUNET_memcpy (term_data, | ||
786 | handle->rest_handle->data, | ||
787 | handle->rest_handle->data_size); | ||
788 | data_js = json_loads (term_data, | ||
789 | JSON_DECODE_ANY, | ||
790 | &err); | ||
791 | GNUNET_assert (GNUNET_OK == | ||
792 | GNUNET_JSON_parse (data_js, docspec, | ||
793 | NULL, NULL)); | ||
794 | json_decref (data_js); | 673 | json_decref (data_js); |
795 | if (NULL == json_obj) | 674 | |
675 | //change zone if pubkey or name specified | ||
676 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY, | ||
677 | strlen (GNUNET_REST_API_PARAM_PUBKEY), | ||
678 | &key); | ||
679 | if ( GNUNET_YES | ||
680 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
681 | &key)) | ||
796 | { | 682 | { |
797 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 683 | pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, |
798 | "Unable to parse JSONAPI Object from %s\n", | 684 | &key); |
799 | term_data); | ||
800 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
801 | return; | ||
802 | } | 685 | } |
803 | if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) | 686 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME, |
687 | strlen (GNUNET_REST_API_PARAM_NAME), | ||
688 | &key); | ||
689 | if ( GNUNET_YES | ||
690 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
691 | &key)) | ||
804 | { | 692 | { |
805 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 693 | name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, |
806 | "Cannot create more than 1 resource! (Got %d)\n", | 694 | &key); |
807 | GNUNET_JSONAPI_document_resource_count (json_obj)); | ||
808 | GNUNET_JSONAPI_document_delete (json_obj); | ||
809 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
810 | return; | ||
811 | } | 695 | } |
812 | json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); | 696 | |
813 | if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, | 697 | ego_entry = get_egoentry(handle,pubkey,name); |
814 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD)) | 698 | if (NULL == ego_entry) |
815 | { | 699 | { |
816 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 700 | if (NULL != pubkey || NULL != name) |
817 | "Unsupported JSON data type\n"); | 701 | { |
818 | GNUNET_JSONAPI_document_delete (json_obj); | 702 | handle->emsg = GNUNET_strdup("Invalid identity"); |
819 | resp = GNUNET_REST_create_response (NULL); | 703 | handle->response_code = MHD_HTTP_NOT_FOUND; |
820 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | 704 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
821 | cleanup_handle (handle); | 705 | return; |
822 | return; | 706 | } |
823 | } | 707 | } |
824 | handle->name = GNUNET_strdup (GNUNET_JSONAPI_resource_get_id (json_res)); | 708 | if ( NULL != ego_entry ) |
825 | records_json = GNUNET_JSONAPI_resource_read_attr (json_res, | ||
826 | GNUNET_REST_JSONAPI_NAMESTORE_RECORD); | ||
827 | if (NULL == records_json) | ||
828 | { | 709 | { |
829 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 710 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); |
830 | "No records given\n"); | ||
831 | GNUNET_JSONAPI_document_delete (json_obj); | ||
832 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
833 | return; | ||
834 | } | 711 | } |
835 | if (GNUNET_SYSERR == json_to_gnsrecord (records_json, &handle->rd, &handle->rd_count)) | 712 | if (NULL == handle->zone_pkey) |
836 | { | 713 | { |
837 | GNUNET_JSONAPI_document_delete (json_obj); | 714 | handle->emsg = GNUNET_strdup("No default identity for namestore"); |
838 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 715 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
839 | return; | 716 | return; |
840 | } | 717 | } |
841 | GNUNET_JSONAPI_document_delete (json_obj); | ||
842 | |||
843 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, | 718 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, |
844 | &handle->zone_pkey, | 719 | handle->zone_pkey, |
845 | handle->name, | 720 | handle->label_name, |
846 | &do_error, | 721 | &do_error, |
847 | handle, | 722 | handle, |
848 | &create_new_record_cont, | 723 | &create_new_record_cont, |
849 | handle); | 724 | handle); |
850 | } | 725 | } |
851 | 726 | ||
852 | 727 | ||
853 | static void | 728 | static void |
854 | namestore_zkey_response (void *cls, | 729 | del_cont (void *cls, |
855 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, | 730 | const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, |
856 | const char *label, | 731 | const char *label, |
857 | unsigned int rd_count, | 732 | unsigned int rd_count, |
858 | const struct GNUNET_GNSRECORD_Data *rd) | 733 | const struct GNUNET_GNSRECORD_Data *rd) |
859 | { | 734 | { |
860 | struct RequestHandle *handle = cls; | 735 | struct RequestHandle *handle = cls; |
861 | struct MHD_Response *resp; | ||
862 | struct GNUNET_JSONAPI_Document *json_obj; | ||
863 | struct GNUNET_JSONAPI_Resource *json_res; | ||
864 | json_t *name_json; | ||
865 | char* result; | ||
866 | 736 | ||
867 | handle->reverse_qe = NULL; | 737 | handle->add_qe = NULL; |
868 | json_obj = GNUNET_JSONAPI_document_new (); | 738 | if (0 == rd_count) |
869 | if (NULL != label) | ||
870 | { | ||
871 | name_json = json_string (label); | ||
872 | json_res = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_NAMESTORE_REVINFO, | ||
873 | handle->zkey_str); | ||
874 | GNUNET_JSONAPI_resource_add_attr (json_res, | ||
875 | GNUNET_REST_JSONAPI_NAMESTORE_NAME, | ||
876 | name_json); | ||
877 | GNUNET_JSONAPI_document_resource_add (json_obj, json_res); | ||
878 | json_decref (name_json); | ||
879 | } | ||
880 | //Handle response | ||
881 | if (GNUNET_SYSERR == GNUNET_JSONAPI_document_serialize (json_obj, &result)) | ||
882 | { | 739 | { |
883 | GNUNET_JSONAPI_document_delete (json_obj); | 740 | handle->emsg = GNUNET_strdup("Record not found"); |
884 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 741 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
885 | return; | 742 | return; |
886 | } | 743 | } |
887 | resp = GNUNET_REST_create_response (result); | ||
888 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
889 | GNUNET_JSONAPI_document_delete (json_obj); | ||
890 | GNUNET_free (result); | ||
891 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | ||
892 | } | ||
893 | 744 | ||
745 | handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, | ||
746 | handle->zone_pkey, | ||
747 | handle->label_name, | ||
748 | 0, NULL, | ||
749 | &del_finished, | ||
750 | handle); | ||
751 | } | ||
894 | 752 | ||
895 | static void | 753 | /** |
896 | namestore_zkey_cont (struct GNUNET_REST_RequestHandle *con, | 754 | * Handle namestore DELETE request |
897 | const char *url, | 755 | * |
898 | void *cls) | 756 | * @param con_handle the connection handle |
757 | * @param url the url | ||
758 | * @param cls the RequestHandle | ||
759 | */ | ||
760 | void | ||
761 | namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, | ||
762 | const char* url, | ||
763 | void *cls) | ||
899 | { | 764 | { |
900 | struct RequestHandle *handle = cls; | 765 | struct RequestHandle *handle = cls; |
901 | struct GNUNET_HashCode key; | 766 | struct GNUNET_HashCode key; |
902 | struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; | 767 | struct EgoEntry *ego_entry = NULL; |
903 | 768 | char *pubkey = NULL; | |
904 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_ZKEY, | 769 | char *name = NULL; |
905 | strlen (GNUNET_REST_JSONAPI_NAMESTORE_ZKEY), | 770 | |
906 | &key); | 771 | //change zone if pubkey or name specified |
907 | if ( GNUNET_NO == | 772 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_PUBKEY, |
908 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | 773 | strlen (GNUNET_REST_API_PARAM_PUBKEY), |
909 | &key) ) | 774 | &key); |
775 | if ( GNUNET_YES | ||
776 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
777 | &key)) | ||
910 | { | 778 | { |
911 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 779 | pubkey = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, |
912 | "No zkey given %s\n", handle->url); | 780 | &key); |
781 | } | ||
782 | GNUNET_CRYPTO_hash (GNUNET_REST_API_PARAM_NAME, | ||
783 | strlen (GNUNET_REST_API_PARAM_NAME), | ||
784 | &key); | ||
785 | if ( GNUNET_YES | ||
786 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
787 | &key)) | ||
788 | { | ||
789 | name = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, | ||
790 | &key); | ||
791 | } | ||
792 | |||
793 | ego_entry = get_egoentry(handle,pubkey,name); | ||
794 | if (NULL == ego_entry) | ||
795 | { | ||
796 | if (NULL != pubkey || NULL != name) | ||
797 | { | ||
798 | handle->emsg = GNUNET_strdup("Invalid identity"); | ||
799 | handle->response_code = MHD_HTTP_NOT_FOUND; | ||
800 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
801 | return; | ||
802 | } | ||
803 | } | ||
804 | if ( NULL != ego_entry ) | ||
805 | { | ||
806 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); | ||
807 | } | ||
808 | |||
809 | GNUNET_CRYPTO_hash ("label", strlen ("label"), &key); | ||
810 | if ( GNUNET_NO | ||
811 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, | ||
812 | &key)) | ||
813 | { | ||
814 | handle->emsg = GNUNET_strdup("Missing name"); | ||
913 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 815 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
914 | return; | 816 | return; |
915 | } | 817 | } |
916 | handle->zkey_str = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | 818 | handle->label_name = GNUNET_strdup( |
917 | &key); | 819 | GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key)); |
918 | if ((NULL == handle->zkey_str) || | 820 | |
919 | (GNUNET_OK != | 821 | if (NULL == handle->zone_pkey) |
920 | GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->zkey_str, | ||
921 | strlen (handle->zkey_str), | ||
922 | &pubkey))) | ||
923 | { | 822 | { |
924 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 823 | handle->emsg = GNUNET_strdup("No default identity for namestore"); |
925 | "Zkey invalid %s\n", handle->zkey_str); | ||
926 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 824 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
927 | return; | 825 | return; |
928 | } | 826 | } |
929 | handle->reverse_qe = GNUNET_NAMESTORE_zone_to_name (handle->ns_handle, | ||
930 | &handle->zone_pkey, | ||
931 | &pubkey, | ||
932 | &do_error, | ||
933 | handle, | ||
934 | &namestore_zkey_response, | ||
935 | handle); | ||
936 | } | ||
937 | |||
938 | 827 | ||
939 | static void | 828 | handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, |
940 | namestore_info_cont (struct GNUNET_REST_RequestHandle *con, | 829 | handle->zone_pkey, |
941 | const char *url, | 830 | handle->label_name, |
942 | void *cls) | 831 | &do_error, |
943 | { | 832 | handle, |
944 | struct RequestHandle *handle = cls; | 833 | &del_cont, |
834 | handle); | ||
945 | 835 | ||
946 | handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, | ||
947 | &handle->zone_pkey, | ||
948 | &do_error, | ||
949 | handle, | ||
950 | &namestore_list_response, | ||
951 | handle, | ||
952 | &namestore_list_finished, | ||
953 | handle); | ||
954 | } | 836 | } |
955 | 837 | ||
956 | 838 | ||
957 | static char* | ||
958 | get_name_from_url (const char* url) | ||
959 | { | ||
960 | if (strlen (url) <= strlen (GNUNET_REST_API_NS_NAMESTORE)) | ||
961 | return NULL; | ||
962 | return (char*)url + strlen (GNUNET_REST_API_NS_NAMESTORE) + 1; | ||
963 | } | ||
964 | 839 | ||
965 | /** | 840 | /** |
966 | * Respond to OPTIONS request | 841 | * Respond to OPTIONS request |
@@ -977,101 +852,72 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
977 | struct MHD_Response *resp; | 852 | struct MHD_Response *resp; |
978 | struct RequestHandle *handle = cls; | 853 | struct RequestHandle *handle = cls; |
979 | 854 | ||
980 | //For now, independent of path return all options | 855 | //independent of path return all options |
981 | resp = GNUNET_REST_create_response (NULL); | 856 | resp = GNUNET_REST_create_response (NULL); |
982 | MHD_add_response_header (resp, | 857 | MHD_add_response_header (resp, |
983 | "Access-Control-Allow-Methods", | 858 | "Access-Control-Allow-Methods", |
984 | allow_methods); | 859 | allow_methods); |
985 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 860 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
986 | cleanup_handle (handle); | 861 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); |
862 | return; | ||
987 | } | 863 | } |
988 | 864 | ||
989 | 865 | ||
990 | /** | 866 | /** |
991 | * Callback invoked from identity service with ego information. | 867 | * Handle rest request |
992 | * An @a ego of NULL means the ego was not found. | ||
993 | * | 868 | * |
994 | * @param cls closure with the configuration | 869 | * @param handle the request handle |
995 | * @param ego an ego known to identity service, or NULL | ||
996 | */ | 870 | */ |
997 | static void | 871 | static void |
998 | identity_cb (void *cls, | 872 | init_cont (struct RequestHandle *handle) |
999 | const struct GNUNET_IDENTITY_Ego *ego) | ||
1000 | { | 873 | { |
1001 | struct RequestHandle *handle = cls; | ||
1002 | struct MHD_Response *resp; | ||
1003 | struct GNUNET_REST_RequestHandlerError err; | 874 | struct GNUNET_REST_RequestHandlerError err; |
1004 | static const struct GNUNET_REST_RequestHandler handlers[] = { | 875 | static const struct GNUNET_REST_RequestHandler handlers[] = { |
1005 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE_ZKEY, &namestore_zkey_cont}, //reverse | 876 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get}, |
1006 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_info_cont}, //list | 877 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add}, |
1007 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_create_cont}, //create | 878 | {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete}, |
1008 | // {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_edit_cont}, //update. TODO this shoul be PATCH | ||
1009 | {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete_cont}, //delete | ||
1010 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont}, | 879 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont}, |
1011 | GNUNET_REST_HANDLER_END | 880 | GNUNET_REST_HANDLER_END |
1012 | }; | 881 | }; |
1013 | 882 | ||
1014 | handle->ego_lookup = NULL; | 883 | if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, |
1015 | if (NULL == ego) | 884 | handlers, |
1016 | { | 885 | &err, |
1017 | if (NULL != handle->ego_name) | 886 | handle)) |
1018 | { | ||
1019 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1020 | _("Ego `%s' not known to identity service\n"), | ||
1021 | handle->ego_name); | ||
1022 | } | ||
1023 | resp = GNUNET_REST_create_response (NULL); | ||
1024 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND); | ||
1025 | cleanup_handle (handle); | ||
1026 | return; | ||
1027 | } | ||
1028 | handle->zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego); | ||
1029 | handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); | ||
1030 | if (NULL == handle->ns_handle) | ||
1031 | { | ||
1032 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1033 | _("Failed to connect to namestore\n")); | ||
1034 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1035 | return; | ||
1036 | } | ||
1037 | |||
1038 | if (GNUNET_OK != | ||
1039 | GNUNET_JSONAPI_handle_request (handle->rest_handle, | ||
1040 | handlers, | ||
1041 | &err, | ||
1042 | handle)) | ||
1043 | { | 887 | { |
1044 | handle->response_code = err.error_code; | 888 | handle->response_code = err.error_code; |
1045 | GNUNET_SCHEDULER_add_now (&do_error, | 889 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
1046 | (void *) handle); | ||
1047 | } | 890 | } |
1048 | } | 891 | } |
1049 | 892 | ||
1050 | 893 | /** | |
894 | * @param cls closure | ||
895 | * @param ego ego handle | ||
896 | * @param ctx context for application to store data for this ego | ||
897 | * (during the lifetime of this process, initially NULL) | ||
898 | * @param identifier identifier assigned by the user for this ego, | ||
899 | * NULL if the user just deleted the ego and it | ||
900 | * must thus no longer be used | ||
901 | */ | ||
1051 | static void | 902 | static void |
1052 | default_ego_cb (void *cls, | 903 | default_ego_cb (void *cls, |
1053 | struct GNUNET_IDENTITY_Ego *ego, | 904 | struct GNUNET_IDENTITY_Ego *ego, |
1054 | void **ctx, | 905 | void **ctx, |
1055 | const char *name) | 906 | const char *identifier) |
1056 | { | 907 | { |
1057 | struct RequestHandle *handle = cls; | 908 | struct RequestHandle *handle = cls; |
1058 | struct MHD_Response *resp; | 909 | handle->op = NULL; |
1059 | handle->get_default = NULL; | 910 | |
1060 | if (NULL == ego) | 911 | if (ego != NULL) |
1061 | { | ||
1062 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1063 | _("No default ego configured in identity service\n")); | ||
1064 | resp = GNUNET_REST_create_response (NULL); | ||
1065 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND); | ||
1066 | cleanup_handle (handle); | ||
1067 | return; | ||
1068 | } | ||
1069 | else | ||
1070 | { | 912 | { |
1071 | identity_cb (cls, ego); | 913 | handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); |
1072 | } | 914 | } |
1073 | } | 915 | } |
1074 | 916 | ||
917 | |||
918 | /** | ||
919 | * Connect to identity callback | ||
920 | */ | ||
1075 | static void | 921 | static void |
1076 | id_connect_cb (void *cls, | 922 | id_connect_cb (void *cls, |
1077 | struct GNUNET_IDENTITY_Ego *ego, | 923 | struct GNUNET_IDENTITY_Ego *ego, |
@@ -1079,12 +925,33 @@ id_connect_cb (void *cls, | |||
1079 | const char *name) | 925 | const char *name) |
1080 | { | 926 | { |
1081 | struct RequestHandle *handle = cls; | 927 | struct RequestHandle *handle = cls; |
1082 | if (NULL == ego) | 928 | struct EgoEntry *ego_entry; |
929 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | ||
930 | |||
931 | if ((NULL == ego) && (NULL == handle->zone_pkey)) | ||
932 | { | ||
933 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
934 | GNUNET_REST_SUBSYSTEM_NAMESTORE, | ||
935 | &default_ego_cb, | ||
936 | handle); | ||
937 | } | ||
938 | if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) | ||
939 | { | ||
940 | handle->state = ID_REST_STATE_POST_INIT; | ||
941 | init_cont (handle); | ||
942 | return; | ||
943 | } | ||
944 | if (ID_REST_STATE_INIT == handle->state) | ||
1083 | { | 945 | { |
1084 | handle->get_default = GNUNET_IDENTITY_get (handle->identity_handle, | 946 | ego_entry = GNUNET_new(struct EgoEntry); |
1085 | "namestore", | 947 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); |
1086 | &default_ego_cb, handle); | 948 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); |
949 | ego_entry->ego = ego; | ||
950 | GNUNET_asprintf (&ego_entry->identifier, "%s", name); | ||
951 | GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail, | ||
952 | ego_entry); | ||
1087 | } | 953 | } |
954 | |||
1088 | } | 955 | } |
1089 | 956 | ||
1090 | 957 | ||
@@ -1097,81 +964,38 @@ id_connect_cb (void *cls, | |||
1097 | * @param data_size length of the body | 964 | * @param data_size length of the body |
1098 | * @param proc callback function for the result | 965 | * @param proc callback function for the result |
1099 | * @param proc_cls closure for callback function | 966 | * @param proc_cls closure for callback function |
1100 | * @return #GNUNET_OK if request accepted | 967 | * @return GNUNET_OK if request accepted |
1101 | */ | 968 | */ |
1102 | static void | 969 | static void |
1103 | rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, | 970 | rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, |
1104 | GNUNET_REST_ResultProcessor proc, | 971 | GNUNET_REST_ResultProcessor proc, |
1105 | void *proc_cls) | 972 | void *proc_cls) |
1106 | { | 973 | { |
1107 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 974 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
1108 | struct MHD_Response *resp; | 975 | |
1109 | struct GNUNET_HashCode key; | 976 | handle->response_code = 0; |
1110 | char *ego; | ||
1111 | char *name; | ||
1112 | char *type; | ||
1113 | |||
1114 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 977 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
1115 | handle->proc_cls = proc_cls; | 978 | handle->proc_cls = proc_cls; |
1116 | handle->proc = proc; | 979 | handle->proc = proc; |
1117 | handle->rest_handle = rest_handle; | 980 | handle->rest_handle = rest_handle; |
981 | handle->zone_pkey = NULL; | ||
982 | |||
1118 | handle->url = GNUNET_strdup (rest_handle->url); | 983 | handle->url = GNUNET_strdup (rest_handle->url); |
1119 | if (handle->url[strlen (handle->url)-1] == '/') | 984 | if (handle->url[strlen (handle->url)-1] == '/') |
1120 | handle->url[strlen (handle->url)-1] = '\0'; | 985 | handle->url[strlen (handle->url)-1] = '\0'; |
1121 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 986 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); |
1122 | "Connecting...\n"); | ||
1123 | handle->cfg = cfg; | ||
1124 | ego = NULL; | ||
1125 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_EGO, | ||
1126 | strlen (GNUNET_REST_JSONAPI_NAMESTORE_EGO), | ||
1127 | &key); | ||
1128 | if ( GNUNET_YES == | ||
1129 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
1130 | &key) ) | ||
1131 | { | ||
1132 | ego = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
1133 | &key); | ||
1134 | } | ||
1135 | 987 | ||
1136 | handle->type = GNUNET_GNSRECORD_TYPE_ANY; | 988 | handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle); |
1137 | GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE, | 989 | handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); |
1138 | strlen (GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE), | 990 | handle->timeout_task = |
1139 | &key); | 991 | GNUNET_SCHEDULER_add_delayed (handle->timeout, |
1140 | if ( GNUNET_YES == | 992 | &do_error, |
1141 | GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | 993 | handle); |
1142 | &key) ) | 994 | |
1143 | { | 995 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); |
1144 | type = GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
1145 | &key); | ||
1146 | if (NULL != type) | ||
1147 | handle->type = GNUNET_GNSRECORD_typename_to_number (type); | ||
1148 | } | ||
1149 | name = get_name_from_url (handle->url); | ||
1150 | if (NULL != ego) | ||
1151 | handle->ego_name = GNUNET_strdup (ego); | ||
1152 | if (NULL != name) | ||
1153 | handle->name = GNUNET_strdup (name); | ||
1154 | if (NULL == handle->ego_name) | ||
1155 | { | ||
1156 | handle->identity_handle = GNUNET_IDENTITY_connect (handle->cfg, &id_connect_cb, handle); | ||
1157 | if (NULL == handle->identity_handle) | ||
1158 | { | ||
1159 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Cannot connect to identity service\n")); | ||
1160 | resp = GNUNET_REST_create_response (NULL); | ||
1161 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND); | ||
1162 | cleanup_handle (handle); | ||
1163 | } | ||
1164 | return; | ||
1165 | } | ||
1166 | handle->ego_lookup = GNUNET_IDENTITY_ego_lookup (cfg, | ||
1167 | handle->ego_name, | ||
1168 | &identity_cb, | ||
1169 | handle); | ||
1170 | handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, | ||
1171 | &do_timeout, | ||
1172 | handle); | ||
1173 | } | 996 | } |
1174 | 997 | ||
998 | |||
1175 | /** | 999 | /** |
1176 | * Entry point for the plugin. | 1000 | * Entry point for the plugin. |
1177 | * | 1001 | * |
@@ -1182,9 +1006,9 @@ void * | |||
1182 | libgnunet_plugin_rest_namestore_init (void *cls) | 1006 | libgnunet_plugin_rest_namestore_init (void *cls) |
1183 | { | 1007 | { |
1184 | static struct Plugin plugin; | 1008 | static struct Plugin plugin; |
1185 | cfg = cls; | ||
1186 | struct GNUNET_REST_Plugin *api; | 1009 | struct GNUNET_REST_Plugin *api; |
1187 | 1010 | ||
1011 | cfg = cls; | ||
1188 | if (NULL != plugin.cfg) | 1012 | if (NULL != plugin.cfg) |
1189 | return NULL; /* can only initialize once! */ | 1013 | return NULL; /* can only initialize once! */ |
1190 | memset (&plugin, 0, sizeof (struct Plugin)); | 1014 | memset (&plugin, 0, sizeof (struct Plugin)); |
@@ -1192,7 +1016,7 @@ libgnunet_plugin_rest_namestore_init (void *cls) | |||
1192 | api = GNUNET_new (struct GNUNET_REST_Plugin); | 1016 | api = GNUNET_new (struct GNUNET_REST_Plugin); |
1193 | api->cls = &plugin; | 1017 | api->cls = &plugin; |
1194 | api->name = GNUNET_REST_API_NS_NAMESTORE; | 1018 | api->name = GNUNET_REST_API_NS_NAMESTORE; |
1195 | api->process_request = &rest_identity_process_request; | 1019 | api->process_request = &rest_process_request; |
1196 | GNUNET_asprintf (&allow_methods, | 1020 | GNUNET_asprintf (&allow_methods, |
1197 | "%s, %s, %s, %s, %s", | 1021 | "%s, %s, %s, %s, %s", |
1198 | MHD_HTTP_METHOD_GET, | 1022 | MHD_HTTP_METHOD_GET, |
@@ -1200,7 +1024,8 @@ libgnunet_plugin_rest_namestore_init (void *cls) | |||
1200 | MHD_HTTP_METHOD_PUT, | 1024 | MHD_HTTP_METHOD_PUT, |
1201 | MHD_HTTP_METHOD_DELETE, | 1025 | MHD_HTTP_METHOD_DELETE, |
1202 | MHD_HTTP_METHOD_OPTIONS); | 1026 | MHD_HTTP_METHOD_OPTIONS); |
1203 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1027 | |
1028 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1204 | _("Namestore REST API initialized\n")); | 1029 | _("Namestore REST API initialized\n")); |
1205 | return api; | 1030 | return api; |
1206 | } | 1031 | } |
@@ -1217,13 +1042,14 @@ libgnunet_plugin_rest_namestore_done (void *cls) | |||
1217 | { | 1042 | { |
1218 | struct GNUNET_REST_Plugin *api = cls; | 1043 | struct GNUNET_REST_Plugin *api = cls; |
1219 | struct Plugin *plugin = api->cls; | 1044 | struct Plugin *plugin = api->cls; |
1220 | |||
1221 | plugin->cfg = NULL; | 1045 | plugin->cfg = NULL; |
1222 | GNUNET_free (api); | 1046 | |
1223 | GNUNET_free_non_null (allow_methods); | 1047 | GNUNET_free_non_null (allow_methods); |
1048 | GNUNET_free (api); | ||
1224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1049 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1225 | "Namestore REST plugin is finished\n"); | 1050 | "Namestore REST plugin is finished\n"); |
1226 | return NULL; | 1051 | return NULL; |
1227 | } | 1052 | } |
1228 | 1053 | ||
1229 | /* end of plugin_rest_namestore.c */ | 1054 | /* end of plugin_rest_namestore.c */ |
1055 | |||