From a31198a7231bc072f428eccb57a45db5dfc65105 Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Thu, 27 Sep 2018 19:31:50 +0200 Subject: bye bye jsonapi --- po/POTFILES.in | 128 ++-- src/Makefile.am | 2 +- src/jsonapi/.gitignore | 1 - src/jsonapi/Makefile.am | 70 -- src/jsonapi/jsonapi.c | 82 --- src/jsonapi/jsonapi_document.c | 402 ---------- src/jsonapi/jsonapi_error.c | 241 ------ src/jsonapi/jsonapi_objects.h | 162 ----- src/jsonapi/jsonapi_relationship.c | 17 - src/jsonapi/jsonapi_resource.c | 367 ---------- src/jsonapi/plugin_rest_reclaim.c | 1253 -------------------------------- src/jsonapi/test_jsonapi.c | 190 ----- src/rest-plugins/Makefile.am | 21 +- src/rest-plugins/json_reclaim.c | 242 ++++++ src/rest-plugins/json_reclaim.h | 46 ++ src/rest-plugins/plugin_rest_reclaim.c | 1097 ++++++++++++++++++++++++++++ 16 files changed, 1468 insertions(+), 2853 deletions(-) delete mode 100644 src/jsonapi/.gitignore delete mode 100644 src/jsonapi/Makefile.am delete mode 100644 src/jsonapi/jsonapi.c delete mode 100644 src/jsonapi/jsonapi_document.c delete mode 100644 src/jsonapi/jsonapi_error.c delete mode 100644 src/jsonapi/jsonapi_objects.h delete mode 100644 src/jsonapi/jsonapi_relationship.c delete mode 100644 src/jsonapi/jsonapi_resource.c delete mode 100644 src/jsonapi/plugin_rest_reclaim.c delete mode 100644 src/jsonapi/test_jsonapi.c create mode 100644 src/rest-plugins/json_reclaim.c create mode 100644 src/rest-plugins/json_reclaim.h create mode 100644 src/rest-plugins/plugin_rest_reclaim.c diff --git a/po/POTFILES.in b/po/POTFILES.in index 44bd751e4..49e4b64ac 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,13 +4,21 @@ src/arm/arm_monitor_api.c src/arm/gnunet-arm.c src/arm/gnunet-service-arm.c src/arm/mockup-service.c +src/ats-tests/ats-testing-experiment.c +src/ats-tests/ats-testing-log.c +src/ats-tests/ats-testing-preferences.c +src/ats-tests/ats-testing-traffic.c +src/ats-tests/ats-testing.c +src/ats-tests/gnunet-ats-sim.c +src/ats-tests/gnunet-solver-eval.c +src/ats-tool/gnunet-ats.c src/ats/ats_api_connectivity.c src/ats/ats_api_performance.c src/ats/ats_api_scanner.c src/ats/ats_api_scheduling.c src/ats/gnunet-ats-solver-eval.c -src/ats/gnunet-service-ats_addresses.c src/ats/gnunet-service-ats.c +src/ats/gnunet-service-ats_addresses.c src/ats/gnunet-service-ats_connectivity.c src/ats/gnunet-service-ats_normalization.c src/ats/gnunet-service-ats_performance.c @@ -21,14 +29,6 @@ src/ats/gnunet-service-ats_scheduling.c src/ats/plugin_ats_mlp.c src/ats/plugin_ats_proportional.c src/ats/plugin_ats_ril.c -src/ats-tests/ats-testing.c -src/ats-tests/ats-testing-experiment.c -src/ats-tests/ats-testing-log.c -src/ats-tests/ats-testing-preferences.c -src/ats-tests/ats-testing-traffic.c -src/ats-tests/gnunet-ats-sim.c -src/ats-tests/gnunet-solver-eval.c -src/ats-tool/gnunet-ats.c src/auction/gnunet-auction-create.c src/auction/gnunet-auction-info.c src/auction/gnunet-auction-join.c @@ -40,8 +40,8 @@ src/block/plugin_block_test.c src/cadet/cadet_api.c src/cadet/cadet_test_lib.c src/cadet/desirability_table.c -src/cadet/gnunet-cadet.c src/cadet/gnunet-cadet-profiler.c +src/cadet/gnunet-cadet.c src/cadet/gnunet-service-cadet.c src/cadet/gnunet-service-cadet_channel.c src/cadet/gnunet-service-cadet_connection.c @@ -57,15 +57,15 @@ src/consensus/gnunet-service-consensus.c src/consensus/plugin_block_consensus.c src/conversation/conversation_api.c src/conversation/conversation_api_call.c -src/conversation/gnunet-conversation.c src/conversation/gnunet-conversation-test.c -src/conversation/gnunet_gst.c -src/conversation/gnunet_gst_test.c -src/conversation/gnunet-helper-audio-playback.c +src/conversation/gnunet-conversation.c src/conversation/gnunet-helper-audio-playback-gst.c -src/conversation/gnunet-helper-audio-record.c +src/conversation/gnunet-helper-audio-playback.c src/conversation/gnunet-helper-audio-record-gst.c +src/conversation/gnunet-helper-audio-record.c src/conversation/gnunet-service-conversation.c +src/conversation/gnunet_gst.c +src/conversation/gnunet_gst_test.c src/conversation/microphone.c src/conversation/plugin_gnsrecord_conversation.c src/conversation/speaker.c @@ -82,7 +82,6 @@ src/credential/credential_serialization.c src/credential/gnunet-credential.c src/credential/gnunet-service-credential.c src/credential/plugin_gnsrecord_credential.c -src/credential/plugin_rest_credential.c src/curl/curl.c src/curl/curl_reschedule.c src/datacache/datacache.c @@ -102,7 +101,6 @@ src/dht/dht_api.c src/dht/dht_test_lib.c src/dht/gnunet-dht-get.c src/dht/gnunet-dht-monitor.c -src/dht/gnunet_dht_profiler.c src/dht/gnunet-dht-put.c src/dht/gnunet-service-dht.c src/dht/gnunet-service-dht_clients.c @@ -111,6 +109,7 @@ src/dht/gnunet-service-dht_hello.c src/dht/gnunet-service-dht_neighbours.c src/dht/gnunet-service-dht_nse.c src/dht/gnunet-service-dht_routing.c +src/dht/gnunet_dht_profiler.c src/dht/plugin_block_dht.c src/dns/dns_api.c src/dns/gnunet-dns-monitor.c @@ -124,8 +123,8 @@ src/dv/gnunet-dv.c src/dv/gnunet-service-dv.c src/dv/plugin_transport_dv.c src/exit/gnunet-daemon-exit.c -src/exit/gnunet-helper-exit.c src/exit/gnunet-helper-exit-windows.c +src/exit/gnunet-helper-exit.c src/fragmentation/defragmentation.c src/fragmentation/fragmentation.c src/fs/fs_api.c @@ -150,8 +149,8 @@ src/fs/gnunet-auto-share.c src/fs/gnunet-daemon-fsprofiler.c src/fs/gnunet-directory.c src/fs/gnunet-download.c -src/fs/gnunet-fs.c src/fs/gnunet-fs-profiler.c +src/fs/gnunet-fs.c src/fs/gnunet-helper-fs-publish.c src/fs/gnunet-publish.c src/fs/gnunet-search.c @@ -171,10 +170,10 @@ src/gns/gns_tld_api.c src/gns/gnunet-bcd.c src/gns/gnunet-dns2gns.c src/gns/gnunet-gns-benchmark.c -src/gns/gnunet-gns.c src/gns/gnunet-gns-helper-service-w32.c src/gns/gnunet-gns-import.c src/gns/gnunet-gns-proxy.c +src/gns/gnunet-gns.c src/gns/gnunet-service-gns.c src/gns/gnunet-service-gns_interceptor.c src/gns/gnunet-service-gns_resolver.c @@ -182,15 +181,15 @@ src/gns/nss/nss_gns.c src/gns/nss/nss_gns_query.c src/gns/plugin_block_gns.c src/gns/plugin_gnsrecord_gns.c +src/gns/w32nsp-install.c +src/gns/w32nsp-resolve.c +src/gns/w32nsp-uninstall.c +src/gns/w32nsp.c src/gnsrecord/gnsrecord.c src/gnsrecord/gnsrecord_crypto.c src/gnsrecord/gnsrecord_misc.c src/gnsrecord/gnsrecord_serialization.c src/gnsrecord/plugin_gnsrecord_dns.c -src/gns/w32nsp.c -src/gns/w32nsp-install.c -src/gns/w32nsp-resolve.c -src/gns/w32nsp-uninstall.c src/hello/address.c src/hello/gnunet-hello.c src/hello/hello.c @@ -201,17 +200,16 @@ src/identity/gnunet-identity.c src/identity/gnunet-service-identity.c src/identity/identity_api.c src/identity/identity_api_lookup.c -src/jsonapi/jsonapi.c -src/jsonapi/jsonapi_document.c -src/jsonapi/jsonapi_error.c -src/jsonapi/jsonapi_relationship.c -src/jsonapi/jsonapi_resource.c -src/jsonapi/plugin_rest_reclaim.c src/json/json.c src/json/json_generator.c src/json/json_gnsrecord.c src/json/json_helper.c src/json/json_mhd.c +src/jsonapi/jsonapi.c +src/jsonapi/jsonapi_document.c +src/jsonapi/jsonapi_error.c +src/jsonapi/jsonapi_relationship.c +src/jsonapi/jsonapi_resource.c src/multicast/gnunet-multicast.c src/multicast/gnunet-service-multicast.c src/multicast/multicast_api.c @@ -225,8 +223,8 @@ src/namecache/namecache_api.c src/namecache/plugin_namecache_flat.c src/namecache/plugin_namecache_postgres.c src/namecache/plugin_namecache_sqlite.c -src/namestore/gnunet-namestore.c src/namestore/gnunet-namestore-fcfsd.c +src/namestore/gnunet-namestore.c src/namestore/gnunet-service-namestore.c src/namestore/gnunet-zoneimport.c src/namestore/namestore_api.c @@ -241,10 +239,10 @@ src/nat-auto/gnunet-service-nat-auto.c src/nat-auto/gnunet-service-nat-auto_legacy.c src/nat-auto/nat_auto_api.c src/nat-auto/nat_auto_api_test.c -src/nat/gnunet-helper-nat-client.c src/nat/gnunet-helper-nat-client-windows.c -src/nat/gnunet-helper-nat-server.c +src/nat/gnunet-helper-nat-client.c src/nat/gnunet-helper-nat-server-windows.c +src/nat/gnunet-helper-nat-server.c src/nat/gnunet-nat.c src/nat/gnunet-service-nat.c src/nat/gnunet-service-nat_externalip.c @@ -253,15 +251,15 @@ src/nat/gnunet-service-nat_mini.c src/nat/gnunet-service-nat_stun.c src/nat/nat_api.c src/nat/nat_api_stun.c -src/nse/gnunet-nse.c src/nse/gnunet-nse-profiler.c +src/nse/gnunet-nse.c src/nse/gnunet-service-nse.c src/nse/nse_api.c +src/peerinfo-tool/gnunet-peerinfo.c +src/peerinfo-tool/gnunet-peerinfo_plugins.c src/peerinfo/gnunet-service-peerinfo.c src/peerinfo/peerinfo_api.c src/peerinfo/peerinfo_api_notify.c -src/peerinfo-tool/gnunet-peerinfo.c -src/peerinfo-tool/gnunet-peerinfo_plugins.c src/peerstore/gnunet-peerstore.c src/peerstore/gnunet-service-peerstore.c src/peerstore/peerstore_api.c @@ -308,34 +306,38 @@ src/regex/regex_internal_dht.c src/regex/regex_test_graph.c src/regex/regex_test_lib.c src/regex/regex_test_random.c -src/rest/gnunet-rest-server.c +src/rest-plugins/json_reclaim.c src/rest-plugins/oidc_helper.c src/rest-plugins/plugin_rest_copying.c +src/rest-plugins/plugin_rest_credential.c src/rest-plugins/plugin_rest_gns.c src/rest-plugins/plugin_rest_identity.c src/rest-plugins/plugin_rest_namestore.c src/rest-plugins/plugin_rest_openid_connect.c src/rest-plugins/plugin_rest_peerinfo.c +src/rest-plugins/plugin_rest_reclaim.c +src/rest/gnunet-rest-server.c src/rest/rest.c src/revocation/gnunet-revocation.c src/revocation/gnunet-service-revocation.c src/revocation/plugin_block_revocation.c src/revocation/revocation_api.c -src/rps/gnunet-rps.c src/rps/gnunet-rps-profiler.c +src/rps/gnunet-rps.c src/rps/gnunet-service-rps.c src/rps/gnunet-service-rps_custommap.c src/rps/gnunet-service-rps_sampler.c src/rps/gnunet-service-rps_sampler_elem.c src/rps/gnunet-service-rps_view.c -src/rps/rps_api.c -src/rps/rps_test_lib.c +src/rps/rps-sampler_client.c +src/rps/rps-sampler_common.c src/rps/rps-test_util.c +src/rps/rps_api.c src/scalarproduct/gnunet-scalarproduct.c -src/scalarproduct/gnunet-service-scalarproduct_alice.c -src/scalarproduct/gnunet-service-scalarproduct_bob.c src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c +src/scalarproduct/gnunet-service-scalarproduct_alice.c +src/scalarproduct/gnunet-service-scalarproduct_bob.c src/scalarproduct/scalarproduct_api.c src/secretsharing/gnunet-secretsharing-profiler.c src/secretsharing/gnunet-service-secretsharing.c @@ -364,15 +366,16 @@ src/statistics/gnunet-statistics.c src/statistics/statistics_api.c src/template/gnunet-service-template.c src/template/gnunet-template.c +src/testbed-logger/gnunet-service-testbed-logger.c +src/testbed-logger/testbed_logger_api.c src/testbed/generate-underlay-topology.c src/testbed/gnunet-daemon-latency-logger.c src/testbed/gnunet-daemon-testbed-blacklist.c src/testbed/gnunet-daemon-testbed-underlay.c src/testbed/gnunet-helper-testbed.c -src/testbed/gnunet_mpi_test.c src/testbed/gnunet-service-test-barriers.c -src/testbed/gnunet-service-testbed_barriers.c src/testbed/gnunet-service-testbed.c +src/testbed/gnunet-service-testbed_barriers.c src/testbed/gnunet-service-testbed_cache.c src/testbed/gnunet-service-testbed_connectionpool.c src/testbed/gnunet-service-testbed_cpustatus.c @@ -380,20 +383,19 @@ src/testbed/gnunet-service-testbed_links.c src/testbed/gnunet-service-testbed_meminfo.c src/testbed/gnunet-service-testbed_oc.c src/testbed/gnunet-service-testbed_peers.c -src/testbed/gnunet_testbed_mpi_spawn.c src/testbed/gnunet-testbed-profiler.c -src/testbed-logger/gnunet-service-testbed-logger.c -src/testbed-logger/testbed_logger_api.c -src/testbed/testbed_api_barriers.c +src/testbed/gnunet_mpi_test.c +src/testbed/gnunet_testbed_mpi_spawn.c src/testbed/testbed_api.c +src/testbed/testbed_api_barriers.c src/testbed/testbed_api_hosts.c src/testbed/testbed_api_operations.c src/testbed/testbed_api_peers.c src/testbed/testbed_api_sd.c src/testbed/testbed_api_services.c src/testbed/testbed_api_statistics.c -src/testbed/testbed_api_testbed.c src/testbed/testbed_api_test.c +src/testbed/testbed_api_testbed.c src/testbed/testbed_api_topology.c src/testbed/testbed_api_underlay.c src/testing/gnunet-testing.c @@ -402,28 +404,28 @@ src/testing/testing.c src/topology/friends.c src/topology/gnunet-daemon-topology.c src/transport/gnunet-helper-transport-bluetooth.c -src/transport/gnunet-helper-transport-wlan.c src/transport/gnunet-helper-transport-wlan-dummy.c -src/transport/gnunet-service-transport_ats.c +src/transport/gnunet-helper-transport-wlan.c src/transport/gnunet-service-transport.c +src/transport/gnunet-service-transport_ats.c src/transport/gnunet-service-transport_hello.c src/transport/gnunet-service-transport_manipulation.c src/transport/gnunet-service-transport_neighbours.c src/transport/gnunet-service-transport_plugins.c src/transport/gnunet-service-transport_validation.c -src/transport/gnunet-transport.c src/transport/gnunet-transport-certificate-creation.c src/transport/gnunet-transport-profiler.c src/transport/gnunet-transport-wlan-receiver.c src/transport/gnunet-transport-wlan-sender.c +src/transport/gnunet-transport.c src/transport/plugin_transport_http_client.c src/transport/plugin_transport_http_common.c src/transport/plugin_transport_http_server.c src/transport/plugin_transport_smtp.c src/transport/plugin_transport_tcp.c src/transport/plugin_transport_template.c -src/transport/plugin_transport_udp_broadcasting.c src/transport/plugin_transport_udp.c +src/transport/plugin_transport_udp_broadcasting.c src/transport/plugin_transport_unix.c src/transport/plugin_transport_wlan.c src/transport/plugin_transport_xt.c @@ -432,6 +434,11 @@ src/transport/tcp_connection_legacy.c src/transport/tcp_server_legacy.c src/transport/tcp_server_mst_legacy.c src/transport/tcp_service_legacy.c +src/transport/transport-testing-filenames.c +src/transport/transport-testing-loggers.c +src/transport/transport-testing-main.c +src/transport/transport-testing-send.c +src/transport/transport-testing.c src/transport/transport_api_address_to_string.c src/transport/transport_api_blacklist.c src/transport/transport_api_core.c @@ -440,11 +447,6 @@ src/transport/transport_api_manipulation.c src/transport/transport_api_monitor_peers.c src/transport/transport_api_monitor_plugins.c src/transport/transport_api_offer_hello.c -src/transport/transport-testing.c -src/transport/transport-testing-filenames.c -src/transport/transport-testing-loggers.c -src/transport/transport-testing-main.c -src/transport/transport-testing-send.c src/util/bandwidth.c src/util/benchmark.c src/util/bio.c @@ -457,8 +459,8 @@ src/util/configuration_loader.c src/util/container_bloomfilter.c src/util/container_heap.c src/util/container_meta_data.c -src/util/container_multihashmap32.c src/util/container_multihashmap.c +src/util/container_multihashmap32.c src/util/container_multipeermap.c src/util/container_multishortmap.c src/util/crypto_abe.c @@ -480,15 +482,15 @@ src/util/dnsparser.c src/util/dnsstub.c src/util/getopt.c src/util/getopt_helpers.c -src/util/gnunet-config.c src/util/gnunet-config-diff.c +src/util/gnunet-config.c src/util/gnunet-ecc.c src/util/gnunet-helper-w32-console.c src/util/gnunet-resolver.c src/util/gnunet-scrypt.c src/util/gnunet-service-resolver.c -src/util/gnunet-timeout.c src/util/gnunet-timeout-w32.c +src/util/gnunet-timeout.c src/util/gnunet-uri.c src/util/helper.c src/util/load.c @@ -516,13 +518,13 @@ src/util/tun.c src/util/w32cat.c src/util/win.c src/util/winproc.c -src/vpn/gnunet-helper-vpn.c src/vpn/gnunet-helper-vpn-windows.c +src/vpn/gnunet-helper-vpn.c src/vpn/gnunet-service-vpn.c src/vpn/gnunet-vpn.c src/vpn/vpn_api.c -src/zonemaster/gnunet-service-zonemaster.c src/zonemaster/gnunet-service-zonemaster-monitor.c +src/zonemaster/gnunet-service-zonemaster.c src/fs/fs_api.h src/include/gnunet_common.h src/include/gnunet_mq_lib.h diff --git a/src/Makefile.am b/src/Makefile.am index 7f97190d0..39cbaa893 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,7 +66,7 @@ endif if HAVE_MHD if HAVE_JSON - REST_DIR = rest jsonapi rest-plugins + REST_DIR = rest rest-plugins endif endif diff --git a/src/jsonapi/.gitignore b/src/jsonapi/.gitignore deleted file mode 100644 index 077606988..000000000 --- a/src/jsonapi/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test_jsonapi diff --git a/src/jsonapi/Makefile.am b/src/jsonapi/Makefile.am deleted file mode 100644 index e572ffa9d..000000000 --- a/src/jsonapi/Makefile.am +++ /dev/null @@ -1,70 +0,0 @@ -# This Makefile.am is in the public domain -AM_CPPFLAGS = -I$(top_srcdir)/src/include - -plugindir = $(libdir)/gnunet - -if USE_COVERAGE - AM_CFLAGS = --coverage -O0 - XLIB = -lgcov -endif - -lib_LTLIBRARIES = \ - libgnunetjsonapi.la \ - libgnunetjsonapiutils.la - -if HAVE_ABE -lib_LTLIBRARIES += libgnunet_plugin_rest_reclaim.la -endif - -libgnunet_plugin_rest_reclaim_la_SOURCES = \ - plugin_rest_reclaim.c -libgnunet_plugin_rest_reclaim_la_LIBADD = \ - $(top_builddir)/src/identity/libgnunetidentity.la \ - $(top_builddir)/src/reclaim/libgnunetreclaim.la \ - $(top_builddir)/src/rest/libgnunetrest.la \ - libgnunetjsonapi.la \ - $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \ - $(top_builddir)/src/namestore/libgnunetnamestore.la \ - $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ - $(LTLIBINTL) -ljansson -lmicrohttpd -libgnunet_plugin_rest_reclaim_la_LDFLAGS = \ - i$(GN_PLUGIN_LDFLAGS) - - -libgnunetjsonapiutils_la_LDFLAGS = \ - -version-info 0:0:0 \ - -no-undefined -libgnunetjsonapiutils_la_SOURCES = \ - jsonapi.c -libgnunetjsonapiutils_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/rest/libgnunetrest.la \ - $(XLIB) - -libgnunetjsonapi_la_LDFLAGS = \ - -version-info 0:0:0 \ - -no-undefined -libgnunetjsonapi_la_SOURCES = \ - jsonapi_document.c jsonapi_objects.h \ - jsonapi_resource.c \ - jsonapi_error.c \ - jsonapi_relationship.c -libgnunetjsonapi_la_LIBADD = \ - $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/json/libgnunetjson.la \ - -ljansson \ - $(XLIB) - -check_PROGRAMS = \ - test_jsonapi - -TESTS = \ - $(check_PROGRAMS) - -test_jsonapi_SOURCES = \ - test_jsonapi.c -test_jsonapi_LDADD = \ - libgnunetjsonapi.la \ - $(top_builddir)/src/json/libgnunetjson.la \ - $(top_builddir)/src/util/libgnunetutil.la \ - -ljansson diff --git a/src/jsonapi/jsonapi.c b/src/jsonapi/jsonapi.c deleted file mode 100644 index f7fcd972a..000000000 --- a/src/jsonapi/jsonapi.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - This file is part of GNUnet - Copyright (C) 2014, 2015, 2016 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . -*/ -/** - * @file jsonapi/jsonapi.c - * @brief functions to generate specifciations for JSONAPI parsing - * @author Martin Schanzenbach - */ -#include "platform.h" -#include "gnunet_json_lib.h" -#include "gnunet_rest_lib.h" - -/** - * TODO move this to jsonapi-utils - */ - -/** - * Check rest request for validity - * - * @param req handle to the request - * @return GNUNET_OK if valid - */ -int -GNUNET_JSONAPI_check_request_acceptable (struct GNUNET_REST_RequestHandle *req) -{ - //TODO - return GNUNET_OK; -} - -/** - * Check rest request for validity - * - * @param req handle to the request - * @return GNUNET_OK if valid - */ -int -GNUNET_JSONAPI_check_request_supported (struct GNUNET_REST_RequestHandle *req) -{ - //TODO - return GNUNET_OK; -} - -/** - * Handle jsonapi rest request. Checks request headers for jsonapi compliance - * - * @param req rest request handle - * @param handler rest request handlers - * @param cls closure - * @return GNUNET_OK if successful - */ -int -GNUNET_JSONAPI_handle_request (struct GNUNET_REST_RequestHandle *handle, - const struct GNUNET_REST_RequestHandler *handlers, - struct GNUNET_REST_RequestHandlerError *err, - void *cls) -{ - if (GNUNET_OK != GNUNET_JSONAPI_check_request_acceptable (handle)) - { - err->error_code = MHD_HTTP_NOT_ACCEPTABLE; - return GNUNET_SYSERR; - } - if (GNUNET_OK != GNUNET_JSONAPI_check_request_supported (handle)) - { - err->error_code = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE; - return GNUNET_SYSERR; - } - return GNUNET_REST_handle_request (handle, handlers, err, cls); -} diff --git a/src/jsonapi/jsonapi_document.c b/src/jsonapi/jsonapi_document.c deleted file mode 100644 index 3a60940f6..000000000 --- a/src/jsonapi/jsonapi_document.c +++ /dev/null @@ -1,402 +0,0 @@ - -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_json_lib.h" -#include "jsonapi_objects.h" - -/** - * Get a JSON API object resource count - * - * @param resp the JSON API object - * @return the number of resources - */ -int -GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *doc) -{ - return doc->res_count; -} - -/** - * Get a JSON API object resource by index - * - * @param resp the JSON API object - * @param idx index of the resource - * @return the resource - */ -struct GNUNET_JSONAPI_Resource* -GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *doc, - int idx) -{ - struct GNUNET_JSONAPI_Resource *res; - int i; - - if ((0 == doc->res_count) || - (idx >= doc->res_count)) - return NULL; - res = doc->res_list_head; - for (i = 0; i < idx; i++) - { - res = res->next; - } - return res; -} - -/** - * Delete a JSON API primary data - * - * @param type the JSON API resource type - * @param id the JSON API resource id - * @return a new JSON API resource or NULL on error. - */ -void -GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *doc) -{ - struct GNUNET_JSONAPI_Resource *res; - struct GNUNET_JSONAPI_Resource *res_next; - struct GNUNET_JSONAPI_Error *err; - struct GNUNET_JSONAPI_Error *err_next; - - - for (err = doc->err_list_head; - err != NULL;) - { - err_next = err->next; - GNUNET_CONTAINER_DLL_remove (doc->err_list_head, - doc->err_list_tail, - err); - GNUNET_JSONAPI_error_delete (err); - err = err_next; - } - - for (res = doc->res_list_head; - res != NULL;) - { - res_next = res->next; - GNUNET_CONTAINER_DLL_remove (doc->res_list_head, - doc->res_list_tail, - res); - GNUNET_JSONAPI_resource_delete (res); - res = res_next; - } - - if (NULL != doc->meta) - json_decref (doc->meta); - GNUNET_free (doc); - doc = NULL; -} - -/** - * Create a JSON API primary data - * - * @return a new JSON API resource or NULL on error. - */ -struct GNUNET_JSONAPI_Document* -GNUNET_JSONAPI_document_new () -{ - struct GNUNET_JSONAPI_Document *result; - - result = GNUNET_new (struct GNUNET_JSONAPI_Document); - result->res_count = 0; - result->err_count = 0; - result->meta = 0; - return result; -} - -/** - * Add a JSON API error to document - * - * @param data The JSON API document to add to - * @param res the JSON API error to add - * @return the new number of resources - */ -void -GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc, - struct GNUNET_JSONAPI_Error *err) -{ - GNUNET_CONTAINER_DLL_insert (doc->err_list_head, - doc->err_list_tail, - err); - - doc->err_count++; -} - -/** - * Add a JSON API resource to primary data - * - * @param data The JSON API data to add to - * @param res the JSON API resource to add - * @return the new number of resources - */ -void -GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc, - struct GNUNET_JSONAPI_Resource *res) -{ - GNUNET_CONTAINER_DLL_insert (doc->res_list_head, - doc->res_list_tail, - res); - - doc->res_count++; -} - - -/** - * Parse given JSON object to jsonapi document. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_jsonapiobject (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Document *result; - struct GNUNET_JSONAPI_Error *error; - struct GNUNET_JSONAPI_Resource *resource; - json_t *meta_json; - json_t *resource_json; - json_t *errors_json; - json_t *value; - size_t index; - - struct GNUNET_JSON_Specification jsonapispecerrors[] = { - GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json), - GNUNET_JSON_spec_end() - }; - if (GNUNET_OK != - GNUNET_JSON_parse (root, jsonapispecerrors, - NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "JSONAPI document does not contain error objects\n"); - } else if (!json_is_array (errors_json)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error object is not array!\n"); - GNUNET_JSON_parse_free (jsonapispecerrors); - return GNUNET_SYSERR; - } - struct GNUNET_JSON_Specification jsonapispecmeta[] = { - GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json), - GNUNET_JSON_spec_end() - }; - if (GNUNET_OK != - GNUNET_JSON_parse (root, jsonapispecmeta, - NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "JSONAPI document does not contain error objects\n"); - } - struct GNUNET_JSON_Specification jsonapispecresource[] = { - GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json), - GNUNET_JSON_spec_end() - }; - if (GNUNET_OK != - GNUNET_JSON_parse (root, jsonapispecresource, - NULL, NULL)) - { - if (NULL == errors_json) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "JSONAPI document contains neither error nor data!\n"); - GNUNET_JSON_parse_free (jsonapispecerrors); - GNUNET_JSON_parse_free (jsonapispecmeta); - return GNUNET_SYSERR; - } - } else { - if (NULL != errors_json) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "JSONAPI document contains both error and data!\n"); - GNUNET_JSON_parse_free (jsonapispecerrors); - GNUNET_JSON_parse_free (jsonapispecmeta); - GNUNET_JSON_parse_free (jsonapispecresource); - return GNUNET_SYSERR; - } - } - - result = GNUNET_new (struct GNUNET_JSONAPI_Document); - result->res_count = 0; - result->err_count = 0; - if (NULL != meta_json) - result->meta = json_deep_copy (meta_json); - if (NULL != errors_json) { - json_array_foreach(errors_json, index, value) { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_json_to_error (value, - &error)); - GNUNET_JSONAPI_document_error_add (result, error); - } - } - if (NULL != resource_json) { - if (0 != json_is_array (resource_json)) - { - json_array_foreach(resource_json, index, value) { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_json_to_resource (value, - &resource)); - GNUNET_JSONAPI_document_resource_add (result, resource); - } - } else { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_json_to_resource (resource_json, - &resource)); - GNUNET_JSONAPI_document_resource_add (result, resource); - } - } - if (NULL != errors_json) - GNUNET_JSON_parse_free (jsonapispecerrors); - if (NULL != resource) - GNUNET_JSON_parse_free (jsonapispecresource); - if (NULL != meta_json) - GNUNET_JSON_parse_free (jsonapispecmeta); - *(struct GNUNET_JSONAPI_Document **) spec->ptr = result; - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing RSA public key. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_jsonapiobject (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Document **jsonapi_obj; - jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr; - if (NULL != *jsonapi_obj) - { - GNUNET_JSONAPI_document_delete (*jsonapi_obj); - *jsonapi_obj = NULL; - } -} - -/** - * Add a JSON API resource to primary data - * - * @param data The JSON API data to add to - * @param res the JSON API resource to add - * @return the new number of resources - */ -void -GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp, - struct GNUNET_JSONAPI_Resource *res) -{ - GNUNET_CONTAINER_DLL_remove (resp->res_list_head, - resp->res_list_tail, - res); - resp->res_count--; -} - - -/** - * String serialze jsonapi primary data - * - * @param data the JSON API primary data - * @param result where to store the result - * @return GNUNET_SYSERR on error else GNUNET_OK - */ -int -GNUNET_JSONAPI_document_to_json (const struct GNUNET_JSONAPI_Document *doc, - json_t **root_json) -{ - struct GNUNET_JSONAPI_Resource *res; - struct GNUNET_JSONAPI_Error *error; - json_t *res_json; - json_t *res_json_tmp; - - if ((NULL == doc)) - return GNUNET_SYSERR; - - *root_json = json_object (); - - //Check for errors first - if (doc->err_count != 0) - { - res_json = json_array (); - for (error = doc->err_list_head; - error != NULL; - error = error->next) - { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_error_to_json (error, - &res_json_tmp)); - json_array_append_new (res_json, res_json_tmp); - } - json_object_set_new (*root_json, - GNUNET_JSONAPI_KEY_ERRORS, - res_json); - } else { - if (0 == doc->res_count) - { - res_json = json_null(); - } else { - res_json = json_array (); - for (res = doc->res_list_head; - res != NULL; - res = res->next) - { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_resource_to_json (res, - &res_json_tmp)); - json_array_append_new (res_json, res_json_tmp); - } - } - json_object_set_new (*root_json, - GNUNET_JSONAPI_KEY_DATA, - res_json); - } - json_object_set (*root_json, - GNUNET_JSONAPI_KEY_META, - doc->meta); - return GNUNET_OK; -} - -/** - * String serialze jsonapi primary data - * - * @param data the JSON API primary data - * @param result where to store the result - * @return GNUNET_SYSERR on error else GNUNET_OK - */ -int -GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc, - char **result) -{ - json_t *json_doc; - if (GNUNET_OK != GNUNET_JSONAPI_document_to_json (doc, - &json_doc)) - return GNUNET_SYSERR; - - *result = json_dumps (json_doc, JSON_INDENT(2)); - json_decref (json_doc); - return GNUNET_OK; -} - -/** - * JSON object. - * - * @param name name of the JSON field - * @param[out] jsonp where to store the JSON found under @a name - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_jsonapiobject, - .cleaner = &clean_jsonapiobject, - .cls = NULL, - .field = NULL, - .ptr = jsonapi_object, - .ptr_size = 0, - .size_ptr = NULL - }; - *jsonapi_object = NULL; - return ret; -} - diff --git a/src/jsonapi/jsonapi_error.c b/src/jsonapi/jsonapi_error.c deleted file mode 100644 index 8ce71d26f..000000000 --- a/src/jsonapi/jsonapi_error.c +++ /dev/null @@ -1,241 +0,0 @@ -#include "platform.h" -#include "gnunet_jsonapi_lib.h" -#include "jsonapi_objects.h" - -/** - * Parse json to error object - * - * @param err_json JSON object - * @param[out] err error object - * @return GNUNET_OK on success - */ -int -GNUNET_JSONAPI_json_to_error (json_t *err_json, - struct GNUNET_JSONAPI_Error **err) -{ - struct GNUNET_JSON_Specification jsonapispecerror[] = { - GNUNET_JSON_spec_jsonapi_error (err), - GNUNET_JSON_spec_end() - }; - return GNUNET_JSON_parse (err_json, jsonapispecerror, - NULL, NULL); -} - -/** - * Serialze jsonapi errors - * - * @param data the JSON API errors - * @param result where to store the result - * @return GNUNET_SYSERR on error else GNUNET_OK - */ -int -GNUNET_JSONAPI_error_to_json (const struct GNUNET_JSONAPI_Error *err, - json_t **result) -{ - *result = json_object (); - - if ((NULL != err->id) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_ID, - json_string (err->id)))) - return GNUNET_SYSERR; - if ((NULL != err->status) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_STATUS, - json_string (err->status)))) - return GNUNET_SYSERR; - if ((NULL != err->code) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_CODE, - json_string (err->code)))) - return GNUNET_SYSERR; - - if ((NULL != err->title) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_TITLE, - json_string (err->title)))) - return GNUNET_SYSERR; - if ((NULL != err->detail) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_DETAIL, - json_string (err->detail)))) - return GNUNET_SYSERR; - if ((NULL != err->source) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_SOURCE, - err->source))) - return GNUNET_SYSERR; - if ((NULL != err->links) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_LINKS, - err->links))) - return GNUNET_SYSERR; - if ((NULL != err->meta) && - (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_META, - err->meta))) - return GNUNET_SYSERR; - return GNUNET_OK; -} - - -/** - * Parse given JSON object to jsonapi document. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_jsonapierror (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Error *result; - json_t *pos; - - GNUNET_assert (NULL != root); - result = GNUNET_new (struct GNUNET_JSONAPI_Error); - pos = json_object_get (root, GNUNET_JSONAPI_KEY_ID); - if (json_is_string (pos)) - result->id = GNUNET_strdup (json_string_value (pos)); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_LINKS); - if (json_is_object (pos)) - result->links = json_deep_copy (pos); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_STATUS); - if (json_is_string (pos)) - result->status = GNUNET_strdup (json_string_value (pos)); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_CODE); - if (json_is_string (pos)) - result->code = GNUNET_strdup (json_string_value (pos)); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_TITLE); - if (json_is_string (pos)) - result->title = GNUNET_strdup (json_string_value (pos)); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_DETAIL); - if (json_is_string (pos)) - result->detail = GNUNET_strdup (json_string_value (pos)); - - pos = json_object_get (root, GNUNET_JSONAPI_KEY_SOURCE); - if (json_is_object (pos)) - result->source = json_deep_copy (pos); - pos = json_object_get (root, GNUNET_JSONAPI_KEY_META); - if (json_is_object (pos)) - result->meta = json_deep_copy (pos); - *(struct GNUNET_JSONAPI_Error **) spec->ptr = result; - return GNUNET_OK; -} - -/** - * Create a JSON API error - * - * @param res the JSON error - */ -struct GNUNET_JSONAPI_Error* -GNUNET_JSONAPI_error_new (const char *id, - const char *status, - const char *code, - const char *title, - const char *detail, - json_t *links, - json_t *source, - json_t *meta) -{ - struct GNUNET_JSONAPI_Error *error; - error = GNUNET_new (struct GNUNET_JSONAPI_Error); - - if (NULL != id) - error->id = GNUNET_strdup (id); - if (NULL != status) - error->status = GNUNET_strdup (status); - if (NULL != code) - error->code = GNUNET_strdup (code); - if (NULL != title) - error->title = GNUNET_strdup (title); - if (NULL != detail) - error->detail = GNUNET_strdup (detail); - if (NULL != links) - error->links = json_deep_copy (links); - if (NULL != source) - error->source = json_deep_copy (source); - if (NULL != meta) - error->meta = json_deep_copy (meta); - return error; -} -/** - * Delete a JSON API error - * - * @param res the JSON error - */ -void -GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error) -{ - GNUNET_assert (NULL != error); - - if (NULL != error->id) - GNUNET_free (error->id); - if (NULL != error->status) - GNUNET_free (error->status); - if (NULL != error->code) - GNUNET_free (error->code); - if (NULL != error->title) - GNUNET_free (error->title); - if (NULL != error->detail) - GNUNET_free (error->detail); - if (NULL != error->links) - json_decref (error->links); - if (NULL != error->source) - json_decref (error->source); - if (NULL != error->meta) - json_decref (error->meta); - GNUNET_free (error); -} - - - -/** - * Cleanup data left from parsing RSA public key. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_jsonapierror (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Error **jsonapi_obj; - jsonapi_obj = (struct GNUNET_JSONAPI_Error **) spec->ptr; - if (NULL != *jsonapi_obj) - { - GNUNET_JSONAPI_error_delete (*jsonapi_obj); - *jsonapi_obj = NULL; - } -} -/** - * JSON object. - * - * @param name name of the JSON field - * @param[out] jsonp where to store the JSON found under @a name - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_object) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_jsonapierror, - .cleaner = &clean_jsonapierror, - .cls = NULL, - .field = NULL, - .ptr = jsonapi_object, - .ptr_size = 0, - .size_ptr = NULL - }; - *jsonapi_object = NULL; - return ret; -} - - diff --git a/src/jsonapi/jsonapi_objects.h b/src/jsonapi/jsonapi_objects.h deleted file mode 100644 index 27c64eeb7..000000000 --- a/src/jsonapi/jsonapi_objects.h +++ /dev/null @@ -1,162 +0,0 @@ -#include "platform.h" -#include "gnunet_jsonapi_lib.h" -/** - * jsonapi error object - */ -struct GNUNET_JSONAPI_Error -{ - /** - * DLL - */ - struct GNUNET_JSONAPI_Error *next; - - /** - * DLL - */ - struct GNUNET_JSONAPI_Error *prev; - - /** - * Unique error id - */ - char *id; - - /** - * Links object - */ - json_t *links; - - /** - * HTTP status code for this error - */ - char *status; - - /** - * Application error code - */ - char *code; - - /** - * Error title - */ - char *title; - - /** - * Error details - */ - char *detail; - - /** - * Error source - */ - json_t *source; - - /** - * Meta info for the error - */ - json_t *meta; -}; - -struct GNUNET_JSONAPI_Relationship -{ - /** - * Links object - */ - struct GNUNET_JSONAPI_Link *links; - - /** - * Resource linkage data - */ - struct GNUNET_JSONAPI_Resource *res_list_head; - - /** - * DLL - */ - struct GNUNET_JSONAPI_Resource *res_list_tail; - - /** - * Number of resources in data section - */ - int res_count; - - /** - * Meta information - */ - json_t *meta; -}; - -/** - * A jsonapi resource object - */ -struct GNUNET_JSONAPI_Resource -{ - /** - * DLL - */ - struct GNUNET_JSONAPI_Resource *next; - - /** - * DLL - */ - struct GNUNET_JSONAPI_Resource *prev; - - /** - * Resource type - */ - char *type; - - /** - * Resource ID - */ - char *id; - - /** - * Attributes object - */ - json_t *attr_obj; - - /** - * Relationship - */ - struct GNUNET_JSONAPI_Relationship *relationship; -}; - - -struct GNUNET_JSONAPI_Document -{ - /** - * DLL Resource - */ - struct GNUNET_JSONAPI_Resource *res_list_head; - - /** - * DLL Resource - */ - struct GNUNET_JSONAPI_Resource *res_list_tail; - - /** - * num resources - */ - int res_count; - - /** - * DLL Error - */ - struct GNUNET_JSONAPI_Error *err_list_head; - - /** - * DLL Error - */ - struct GNUNET_JSONAPI_Error *err_list_tail; - - /** - * num errors - */ - int err_count; - - /** - * Meta info - */ - json_t *meta; -}; - - diff --git a/src/jsonapi/jsonapi_relationship.c b/src/jsonapi/jsonapi_relationship.c deleted file mode 100644 index b88e74cc9..000000000 --- a/src/jsonapi/jsonapi_relationship.c +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform.h" -#include "gnunet_jsonapi_lib.h" - - -/** - * Delete a JSON API relationship TODO - * - * @param res the JSON relationship - */ -void -GNUNET_JSONAPI_relationship_delete (struct GNUNET_JSONAPI_Relationship *relationship) -{ - GNUNET_assert (NULL != relationship); - GNUNET_free (relationship); -} - - diff --git a/src/jsonapi/jsonapi_resource.c b/src/jsonapi/jsonapi_resource.c deleted file mode 100644 index be28ad5df..000000000 --- a/src/jsonapi/jsonapi_resource.c +++ /dev/null @@ -1,367 +0,0 @@ -#include "platform.h" -#include "gnunet_jsonapi_lib.h" -#include "jsonapi_objects.h" - -/** - * String serialze jsonapi resources - * - * @param data the JSON API resource - * @param result where to store the result - * @return GNUNET_SYSERR on error else GNUNET_OK - */ -int -GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res, - json_t **result) -{ - struct GNUNET_JSONAPI_Resource *rel_res; - json_t *relationship; - json_t *res_json_tmp; - *result = json_object (); - - if (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_ID, - json_string (res->id))) - return GNUNET_SYSERR; - if (0 != json_object_set_new (*result, - GNUNET_JSONAPI_KEY_TYPE, - json_string (res->type))) - return GNUNET_SYSERR; - if ((NULL != res->attr_obj) && - (0 != json_object_set (*result, - GNUNET_JSONAPI_KEY_ATTRIBUTES, - res->attr_obj))) - return GNUNET_SYSERR; - - //Relationships - if (NULL != res->relationship) - { - relationship = json_object (); - if (0 != res->relationship->res_count) - { - json_t *res_json; - switch (res->relationship->res_count) - { - case 0: - res_json = json_null(); - break; - case 1: - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_resource_to_json (res->relationship->res_list_head, - &res_json)); - break; - default: - res_json = json_array (); - rel_res = NULL; - for (rel_res = res->relationship->res_list_head; - rel_res != NULL; - rel_res = rel_res->next) - { - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_resource_to_json (rel_res, - &res_json_tmp)); - json_array_append_new (res_json, res_json_tmp); - } - break; - } - json_object_set_new (relationship, - GNUNET_JSONAPI_KEY_DATA, - res_json); - } - if ((NULL != res->relationship->meta) && - (0 != json_object_set_new (relationship, - GNUNET_JSONAPI_KEY_META, - res->relationship->meta))) - return GNUNET_SYSERR; - //TODO link - } - - - return GNUNET_OK; -} - - -/** - * Create a JSON API resource - * - * @param type the JSON API resource type - * @param id the JSON API resource id - * @return a new JSON API resource or NULL on error. - */ -struct GNUNET_JSONAPI_Resource* -GNUNET_JSONAPI_resource_new (const char *type, const char *id) -{ - struct GNUNET_JSONAPI_Resource *res; - - if (NULL == type) - return NULL; - if (NULL == id) - return NULL; - - res = GNUNET_new (struct GNUNET_JSONAPI_Resource); - res->prev = NULL; - res->next = NULL; - res->attr_obj = NULL; - res->relationship = NULL; - res->id = GNUNET_strdup (id); - res->type = GNUNET_strdup (type); - return res; -} - -/** - * Add a jsonapi relationship - * @param res the resource to add to - * @param rel the relationship to add - * @return #GNUNETOK if added successfully - */ -int -GNUNET_JSONAPI_resource_set_relationship (struct GNUNET_JSONAPI_Resource *res, - struct GNUNET_JSONAPI_Relationship *rel) -{ - GNUNET_assert (NULL != res); - GNUNET_assert (NULL != rel); - if (NULL != res->relationship) - return GNUNET_SYSERR; - res->relationship = rel; - return GNUNET_OK; -} - -/** - * Add a JSON API attribute - * - * @param res the JSON resource - * @param key the key for the attribute - * @param json the json_t attribute to add - * @return #GNUNET_OK if added successfully - * #GNUNET_SYSERR if not - */ -int -GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource, - const char* key, - json_t *json) -{ - if ( (NULL == resource) || - (NULL == key) || - (NULL == json) ) - return GNUNET_SYSERR; - if (NULL == resource->attr_obj) - resource->attr_obj = json_object (); - json_object_set (resource->attr_obj, key, json); - return GNUNET_OK; -} - -/** - * Read a JSON API attribute - * - * @param res the JSON resource - * @param key the key for the attribute - * @return the json_t object - */ -json_t* -GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource, - const char* key) -{ - if ( (NULL == resource) || - (NULL == key) || - (NULL == resource->attr_obj)) - return NULL; - return json_object_get (resource->attr_obj, key); -} - -int -check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource, - const char* key, - const char* attr) -{ - json_t *value; - if ( (NULL == resource) || - (NULL == key) || - (NULL == attr) || - (NULL == resource->attr_obj)) - return GNUNET_NO; - value = json_object_get (resource->attr_obj, key); - if (NULL == value) - return GNUNET_NO; - if (!json_is_string (value) || - (0 != strcmp (attr, json_string_value(value)))) - { - return GNUNET_NO; - } - return GNUNET_YES; -} - -/** - * Check a JSON API resource type - * - * @param res the JSON resource - * @param type the expected type - * @return GNUNET_YES if id matches - */ -int -GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource, - const char* type) -{ - return (0 == memcmp (type, resource->type, - strlen (resource->type))) ? GNUNET_YES : GNUNET_NO; -} - - -/** - * Delete a JSON API resource - * - * @param res the JSON resource - * @param result Pointer where the resource should be stored - */ -void -GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource) -{ - GNUNET_free (resource->id); - GNUNET_free (resource->type); - if (NULL != resource->attr_obj) - json_decref (resource->attr_obj); - if (NULL != resource->relationship) - GNUNET_JSONAPI_relationship_delete (resource->relationship); - GNUNET_free (resource); - resource = NULL; -} - - -/** - * Check a JSON API resource id - * - * @param res the JSON resource - * @param id the expected id - * @return GNUNET_YES if id matches - */ -int -GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource, - const char* id) -{ - return (0 == memcmp (resource->id, id, strlen (id))) ? GNUNET_YES : GNUNET_NO; -} - -/** - * Check a JSON API resource id - * - * @param res the JSON resource - * @return the resource id - */ -const char* -GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource) -{ - return resource->id; -} - -/** - * Parse json to resource object - * - * @param res_json JSON object - * @param[out] res resource object - * @return GNUNET_OK on success - */ -int -GNUNET_JSONAPI_json_to_resource (json_t *res_json, - struct GNUNET_JSONAPI_Resource **res) -{ - struct GNUNET_JSON_Specification jsonapispecresource[] = { - GNUNET_JSON_spec_jsonapi_resource (res), - GNUNET_JSON_spec_end() - }; - return GNUNET_JSON_parse (res_json, jsonapispecresource, - NULL, NULL); -} - -/** - * Parse given JSON object to jsonapi document. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_jsonapiresource (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Resource *res; - const char *type; - const char *id; - json_t *attrs; - - struct GNUNET_JSON_Specification dspec[] = { - GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type), - GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_ID, &id), - GNUNET_JSON_spec_end() - }; - - if (GNUNET_OK != - GNUNET_JSON_parse (root, dspec, - NULL, NULL)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse resource\n"); - return GNUNET_SYSERR; - } - res = GNUNET_JSONAPI_resource_new (type, id); - GNUNET_JSON_parse_free (dspec); - - struct GNUNET_JSON_Specification attrspec[] = { - GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ATTRIBUTES, &attrs), - GNUNET_JSON_spec_end() - }; - if (GNUNET_OK != - GNUNET_JSON_parse (root, attrspec, - NULL, NULL)) - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resource does not contain attributes\n"); - if (NULL != attrs) - res->attr_obj = json_deep_copy (attrs); - - //TODO relationship - GNUNET_JSON_parse_free (attrspec); - *(struct GNUNET_JSONAPI_Resource **) spec->ptr = res; - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing resource. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_jsonapiresource (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Resource **jsonapi_obj; - jsonapi_obj = (struct GNUNET_JSONAPI_Resource **) spec->ptr; - if (NULL != *jsonapi_obj) - { - GNUNET_JSONAPI_resource_delete (*jsonapi_obj); - *jsonapi_obj = NULL; - } -} - - -/** - * JSON object. - * - * @param name name of the JSON field - * @param[out] jsonp where to store the JSON found under @a name - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_object) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_jsonapiresource, - .cleaner = &clean_jsonapiresource, - .cls = NULL, - .field = NULL, - .ptr = jsonapi_object, - .ptr_size = 0, - .size_ptr = NULL - }; - *jsonapi_object = NULL; - return ret; -} - - diff --git a/src/jsonapi/plugin_rest_reclaim.c b/src/jsonapi/plugin_rest_reclaim.c deleted file mode 100644 index 38ffc4ddb..000000000 --- a/src/jsonapi/plugin_rest_reclaim.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2012-2015 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ -/** - * @author Martin Schanzenbach - * @author Philippe Buschmann - * @file reclaim/plugin_rest_reclaim.c - * @brief GNUnet reclaim REST plugin - * - */ - -#include "platform.h" -#include "gnunet_rest_plugin.h" -#include "gnunet_identity_service.h" -#include "gnunet_gns_service.h" -#include "gnunet_gnsrecord_lib.h" -#include "gnunet_namestore_service.h" -#include "gnunet_rest_lib.h" -#include "gnunet_jsonapi_lib.h" -#include "gnunet_jsonapi_util.h" -#include "microhttpd.h" -#include -#include -#include "gnunet_signatures.h" -#include "gnunet_reclaim_attribute_lib.h" -#include "gnunet_reclaim_service.h" - -/** - * REST root namespace - */ -#define GNUNET_REST_API_NS_RECLAIM "/reclaim" - -/** - * Attribute namespace - */ -#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes" - -/** - * Ticket namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets" - -/** - * Revoke namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke" - -/** - * Revoke namespace - */ -#define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume" - -/** - * Attribute key - */ -#define GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE "attribute" - -/** - * Ticket key - */ -#define GNUNET_REST_JSONAPI_IDENTITY_TICKET "ticket" - - -/** - * Value key - */ -#define GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE_VALUE "value" - -/** - * State while collecting all egos - */ -#define ID_REST_STATE_INIT 0 - -/** - * Done collecting egos - */ -#define ID_REST_STATE_POST_INIT 1 - -/** - * The configuration handle - */ -const struct GNUNET_CONFIGURATION_Handle *cfg; - -/** - * HTTP methods allows for this plugin - */ -static char* allow_methods; - -/** - * @brief struct returned by the initialization function of the plugin - */ -struct Plugin -{ - const struct GNUNET_CONFIGURATION_Handle *cfg; -}; - -/** - * The ego list - */ -struct EgoEntry -{ - /** - * DLL - */ - struct EgoEntry *next; - - /** - * DLL - */ - struct EgoEntry *prev; - - /** - * Ego Identifier - */ - char *identifier; - - /** - * Public key string - */ - char *keystring; - - /** - * The Ego - */ - struct GNUNET_IDENTITY_Ego *ego; -}; - - -struct RequestHandle -{ - /** - * Ego list - */ - struct EgoEntry *ego_head; - - /** - * Ego list - */ - struct EgoEntry *ego_tail; - - /** - * Selected ego - */ - struct EgoEntry *ego_entry; - - /** - * Pointer to ego private key - */ - struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; - - /** - * The processing state - */ - int state; - - /** - * Handle to Identity service. - */ - struct GNUNET_IDENTITY_Handle *identity_handle; - - /** - * Rest connection - */ - struct GNUNET_REST_RequestHandle *rest_handle; - - /** - * Handle to NAMESTORE - */ - struct GNUNET_NAMESTORE_Handle *namestore_handle; - - /** - * Iterator for NAMESTORE - */ - struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; - - /** - * Attribute claim list - */ - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list; - - /** - * IDENTITY Operation - */ - struct GNUNET_IDENTITY_Operation *op; - - /** - * Identity Provider - */ - struct GNUNET_RECLAIM_Handle *idp; - - /** - * Idp Operation - */ - struct GNUNET_RECLAIM_Operation *idp_op; - - /** - * Attribute iterator - */ - struct GNUNET_RECLAIM_AttributeIterator *attr_it; - - /** - * Ticket iterator - */ - struct GNUNET_RECLAIM_TicketIterator *ticket_it; - - /** - * A ticket - */ - struct GNUNET_RECLAIM_Ticket ticket; - - /** - * Desired timeout for the lookup (default is no timeout). - */ - struct GNUNET_TIME_Relative timeout; - - /** - * ID of a task associated with the resolution process. - */ - struct GNUNET_SCHEDULER_Task *timeout_task; - - /** - * The plugin result processor - */ - GNUNET_REST_ResultProcessor proc; - - /** - * The closure of the result processor - */ - void *proc_cls; - - /** - * The url - */ - char *url; - - /** - * Error response message - */ - char *emsg; - - /** - * Reponse code - */ - int response_code; - - /** - * Response object - */ - struct GNUNET_JSONAPI_Document *resp_object; - -}; - -/** - * Cleanup lookup handle - * @param handle Handle to clean up - */ -static void -cleanup_handle (struct RequestHandle *handle) -{ - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry; - struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp; - struct EgoEntry *ego_entry; - struct EgoEntry *ego_tmp; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Cleaning up\n"); - if (NULL != handle->resp_object) - GNUNET_JSONAPI_document_delete (handle->resp_object); - if (NULL != handle->timeout_task) - GNUNET_SCHEDULER_cancel (handle->timeout_task); - if (NULL != handle->identity_handle) - GNUNET_IDENTITY_disconnect (handle->identity_handle); - if (NULL != handle->attr_it) - GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); - if (NULL != handle->ticket_it) - GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); - if (NULL != handle->idp) - GNUNET_RECLAIM_disconnect (handle->idp); - if (NULL != handle->url) - GNUNET_free (handle->url); - if (NULL != handle->emsg) - GNUNET_free (handle->emsg); - if (NULL != handle->namestore_handle) - GNUNET_NAMESTORE_disconnect (handle->namestore_handle); - if ( NULL != handle->attr_list ) - { - for (claim_entry = handle->attr_list->list_head; - NULL != claim_entry;) - { - claim_tmp = claim_entry; - claim_entry = claim_entry->next; - GNUNET_free(claim_tmp->claim); - GNUNET_free(claim_tmp); - } - GNUNET_free (handle->attr_list); - } - for (ego_entry = handle->ego_head; - NULL != ego_entry;) - { - ego_tmp = ego_entry; - ego_entry = ego_entry->next; - GNUNET_free (ego_tmp->identifier); - GNUNET_free (ego_tmp->keystring); - GNUNET_free (ego_tmp); - } - if (NULL != handle->attr_it) - { - GNUNET_free(handle->attr_it); - } - GNUNET_free (handle); -} - -static void -cleanup_handle_delayed (void *cls) -{ - cleanup_handle (cls); -} - - -/** - * Task run on error, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_error (void *cls) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - char *json_error; - - GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }", - handle->emsg); - if ( 0 == handle->response_code ) - { - handle->response_code = MHD_HTTP_BAD_REQUEST; - } - resp = GNUNET_REST_create_response (json_error); - MHD_add_response_header (resp, "Content-Type", "application/json"); - handle->proc (handle->proc_cls, resp, handle->response_code); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); - GNUNET_free (json_error); -} - - -/** - * Task run on timeout, sends error message. Cleans up everything. - * - * @param cls the `struct RequestHandle` - */ -static void -do_timeout (void *cls) -{ - struct RequestHandle *handle = cls; - - handle->timeout_task = NULL; - do_error (handle); -} - - -static void -collect_error_cb (void *cls) -{ - struct RequestHandle *handle = cls; - - do_error (handle); -} - -static void -finished_cont (void *cls, - int32_t success, - const char *emsg) -{ - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - resp = GNUNET_REST_create_response (emsg); - if (GNUNET_OK != success) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); -} - - -/** - * Return attributes for identity - * - * @param cls the request handle - */ -static void -return_response (void *cls) -{ - char* result_str; - struct RequestHandle *handle = cls; - struct MHD_Response *resp; - - GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); - resp = GNUNET_REST_create_response (result_str); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_free (result_str); - cleanup_handle (handle); -} - -static void -collect_finished_cb (void *cls) -{ - struct RequestHandle *handle = cls; - //Done - handle->attr_it = NULL; - handle->ticket_it = NULL; - GNUNET_SCHEDULER_add_now (&return_response, handle); -} - - -/** - * Collect all attributes for an ego - * - */ -static void -ticket_collect (void *cls, - const struct GNUNET_RECLAIM_Ticket *ticket) -{ - struct GNUNET_JSONAPI_Resource *json_resource; - struct RequestHandle *handle = cls; - json_t *value; - char* tmp; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n"); - tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, - sizeof (uint64_t)); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TICKET, - tmp); - GNUNET_free (tmp); - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - - tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - value = json_string (tmp); - GNUNET_JSONAPI_resource_add_attr (json_resource, - "issuer", - value); - GNUNET_free (tmp); - json_decref (value); - tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - value = json_string (tmp); - GNUNET_JSONAPI_resource_add_attr (json_resource, - "audience", - value); - GNUNET_free (tmp); - json_decref (value); - tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, - sizeof (uint64_t)); - value = json_string (tmp); - GNUNET_JSONAPI_resource_add_attr (json_resource, - "rnd", - value); - GNUNET_free (tmp); - json_decref (value); - GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it); -} - - - -/** - * List tickets for identity request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - char *identity; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n", - handle->url); - if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= - strlen (handle->url)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; - - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - if (0 == strcmp (identity, ego_entry->identifier)) - break; - handle->resp_object = GNUNET_JSONAPI_document_new (); - - if (NULL == ego_entry) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", - identity); - GNUNET_SCHEDULER_add_now (&return_response, handle); - return; - } - priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->ticket_it = GNUNET_RECLAIM_ticket_iteration_start (handle->idp, - priv_key, - &collect_error_cb, - handle, - &ticket_collect, - handle, - &collect_finished_cb, - handle); -} - - -static void -add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; - const char* identity; - const char* name_str; - const char* value_str; - const char* exp_str; - - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct MHD_Response *resp; - struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute; - struct GNUNET_JSONAPI_Document *json_obj; - struct GNUNET_JSONAPI_Resource *json_res; - struct GNUNET_TIME_Relative exp; - char term_data[handle->rest_handle->data_size+1]; - json_t *value_json; - json_t *data_json; - json_t *exp_json; - json_error_t err; - struct GNUNET_JSON_Specification docspec[] = { - GNUNET_JSON_spec_jsonapi_document (&json_obj), - GNUNET_JSON_spec_end() - }; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n", - handle->url); - if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= - strlen (handle->url)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - if (0 == strcmp (identity, ego_entry->identifier)) - break; - - if (NULL == ego_entry) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Identity unknown (%s)\n", identity); - GNUNET_JSONAPI_document_delete (json_obj); - return; - } - identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - - if (0 >= handle->rest_handle->data_size) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - term_data[handle->rest_handle->data_size] = '\0'; - GNUNET_memcpy (term_data, - handle->rest_handle->data, - handle->rest_handle->data_size); - data_json = json_loads (term_data, - JSON_DECODE_ANY, - &err); - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (data_json, docspec, - NULL, NULL)); - json_decref (data_json); - if (NULL == json_obj) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to parse JSONAPI Object from %s\n", - term_data); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Cannot create more than 1 resource! (Got %d)\n", - GNUNET_JSONAPI_document_resource_count (json_obj)); - GNUNET_JSONAPI_document_delete (json_obj); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); - if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, - GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unsupported JSON data type\n"); - GNUNET_JSONAPI_document_delete (json_obj); - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); - cleanup_handle (handle); - return; - } - name_str = GNUNET_JSONAPI_resource_get_id (json_res); - exp_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "exp"); - exp_str = json_string_value (exp_json); - if (NULL == exp_str) { - exp = GNUNET_TIME_UNIT_HOURS; - } else { - if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (exp_str, - &exp)) { - exp = GNUNET_TIME_UNIT_HOURS; - } - } - - value_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "value"); - value_str = json_string_value (value_json); - attribute = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, - GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING, - value_str, - strlen (value_str) + 1); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, - identity_priv, - attribute, - &exp, - &finished_cont, - handle); - GNUNET_free (attribute); - GNUNET_JSONAPI_document_delete (json_obj); -} - - - -/** - * Collect all attributes for an ego - * - */ -static void -attr_collect (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) -{ - struct GNUNET_JSONAPI_Resource *json_resource; - struct RequestHandle *handle = cls; - json_t *value; - char* tmp_value; - - if ((NULL == attr->name) || (NULL == attr->data)) - { - GNUNET_RECLAIM_get_attributes_next (handle->attr_it); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", - attr->name); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE, - attr->name); - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - - tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, - attr->data, - attr->data_size); - - value = json_string (tmp_value); - - GNUNET_JSONAPI_resource_add_attr (json_resource, - "value", - value); - json_decref (value); - GNUNET_free(tmp_value); - GNUNET_RECLAIM_get_attributes_next (handle->attr_it); -} - - - -/** - * List attributes for identity request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - char *identity; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n", - handle->url); - if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= - strlen (handle->url)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; - - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - if (0 == strcmp (identity, ego_entry->identifier)) - break; - handle->resp_object = GNUNET_JSONAPI_document_new (); - - - if (NULL == ego_entry) - { - //Done - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", - identity); - GNUNET_SCHEDULER_add_now (&return_response, handle); - return; - } - priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp, - priv_key, - &collect_error_cb, - handle, - &attr_collect, - handle, - &collect_finished_cb, - handle); -} - - -static void -revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; - const char* identity_str; - const char* audience_str; - const char* rnd_str; - - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct MHD_Response *resp; - struct GNUNET_RECLAIM_Ticket ticket; - struct GNUNET_JSONAPI_Document *json_obj; - struct GNUNET_JSONAPI_Resource *json_res; - struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; - char term_data[handle->rest_handle->data_size+1]; - json_t *rnd_json; - json_t *identity_json; - json_t *audience_json; - json_t *data_json; - json_error_t err; - struct GNUNET_JSON_Specification docspec[] = { - GNUNET_JSON_spec_jsonapi_document (&json_obj), - GNUNET_JSON_spec_end() - }; - - if (0 >= handle->rest_handle->data_size) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - term_data[handle->rest_handle->data_size] = '\0'; - GNUNET_memcpy (term_data, - handle->rest_handle->data, - handle->rest_handle->data_size); - data_json = json_loads (term_data, - JSON_DECODE_ANY, - &err); - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (data_json, docspec, - NULL, NULL)); - json_decref (data_json); - if (NULL == json_obj) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to parse JSONAPI Object from %s\n", - term_data); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Cannot create more than 1 resource! (Got %d)\n", - GNUNET_JSONAPI_document_resource_count (json_obj)); - GNUNET_JSONAPI_document_delete (json_obj); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); - if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, - GNUNET_REST_JSONAPI_IDENTITY_TICKET)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unsupported JSON data type\n"); - GNUNET_JSONAPI_document_delete (json_obj); - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); - cleanup_handle (handle); - return; - } - rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "rnd"); - identity_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "issuer"); - audience_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "audience"); - rnd_str = json_string_value (rnd_json); - identity_str = json_string_value (identity_json); - audience_str = json_string_value (audience_json); - - GNUNET_STRINGS_string_to_data (rnd_str, - strlen (rnd_str), - &ticket.rnd, - sizeof (uint64_t)); - GNUNET_STRINGS_string_to_data (identity_str, - strlen (identity_str), - &ticket.identity, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - GNUNET_STRINGS_string_to_data (audience_str, - strlen (audience_str), - &ticket.audience, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - { - GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, - &tmp_pk); - if (0 == memcmp (&ticket.identity, - &tmp_pk, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) - break; - } - if (NULL == ego_entry) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Identity unknown (%s)\n", identity_str); - GNUNET_JSONAPI_document_delete (json_obj); - return; - } - identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp, - identity_priv, - &ticket, - &finished_cont, - handle); - GNUNET_JSONAPI_document_delete (json_obj); -} - -static void -consume_cont (void *cls, - const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, - const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) -{ - struct RequestHandle *handle = cls; - struct GNUNET_JSONAPI_Resource *json_resource; - json_t *value; - - if (NULL == identity) - { - GNUNET_SCHEDULER_add_now (&return_response, handle); - return; - } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", - attr->name); - json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE, - attr->name); - GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - - value = json_string (attr->data); - GNUNET_JSONAPI_resource_add_attr (json_resource, - "value", - value); - json_decref (value); -} - -static void -consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; - const char* identity_str; - const char* audience_str; - const char* rnd_str; - - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct MHD_Response *resp; - struct GNUNET_RECLAIM_Ticket ticket; - struct GNUNET_JSONAPI_Document *json_obj; - struct GNUNET_JSONAPI_Resource *json_res; - struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; - char term_data[handle->rest_handle->data_size+1]; - json_t *rnd_json; - json_t *identity_json; - json_t *audience_json; - json_t *data_json; - json_error_t err; - struct GNUNET_JSON_Specification docspec[] = { - GNUNET_JSON_spec_jsonapi_document (&json_obj), - GNUNET_JSON_spec_end() - }; - - if (0 >= handle->rest_handle->data_size) - { - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - - term_data[handle->rest_handle->data_size] = '\0'; - GNUNET_memcpy (term_data, - handle->rest_handle->data, - handle->rest_handle->data_size); - data_json = json_loads (term_data, - JSON_DECODE_ANY, - &err); - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (data_json, docspec, - NULL, NULL)); - json_decref (data_json); - if (NULL == json_obj) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to parse JSONAPI Object from %s\n", - term_data); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Cannot create more than 1 resource! (Got %d)\n", - GNUNET_JSONAPI_document_resource_count (json_obj)); - GNUNET_JSONAPI_document_delete (json_obj); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); - if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, - GNUNET_REST_JSONAPI_IDENTITY_TICKET)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unsupported JSON data type\n"); - GNUNET_JSONAPI_document_delete (json_obj); - resp = GNUNET_REST_create_response (NULL); - handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); - cleanup_handle (handle); - return; - } - rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "rnd"); - identity_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "identity"); - audience_json = GNUNET_JSONAPI_resource_read_attr (json_res, - "audience"); - rnd_str = json_string_value (rnd_json); - identity_str = json_string_value (identity_json); - audience_str = json_string_value (audience_json); - - GNUNET_STRINGS_string_to_data (rnd_str, - strlen (rnd_str), - &ticket.rnd, - sizeof (uint64_t)); - GNUNET_STRINGS_string_to_data (identity_str, - strlen (identity_str), - &ticket.identity, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - GNUNET_STRINGS_string_to_data (audience_str, - strlen (audience_str), - &ticket.audience, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); - - for (ego_entry = handle->ego_head; - NULL != ego_entry; - ego_entry = ego_entry->next) - { - GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, - &tmp_pk); - if (0 == memcmp (&ticket.audience, - &tmp_pk, - sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) - break; - } - if (NULL == ego_entry) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Identity unknown (%s)\n", identity_str); - GNUNET_JSONAPI_document_delete (json_obj); - return; - } - identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); - handle->resp_object = GNUNET_JSONAPI_document_new (); - handle->idp = GNUNET_RECLAIM_connect (cfg); - handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, - identity_priv, - &ticket, - &consume_cont, - handle); - GNUNET_JSONAPI_document_delete (json_obj); -} - - - -/** - * Respond to OPTIONS request - * - * @param con_handle the connection handle - * @param url the url - * @param cls the RequestHandle - */ -static void -options_cont (struct GNUNET_REST_RequestHandle *con_handle, - const char* url, - void *cls) -{ - struct MHD_Response *resp; - struct RequestHandle *handle = cls; - - //For now, independent of path return all options - resp = GNUNET_REST_create_response (NULL); - MHD_add_response_header (resp, - "Access-Control-Allow-Methods", - allow_methods); - handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - cleanup_handle (handle); - return; -} - -/** - * Handle rest request - * - * @param handle the request handle - */ -static void -init_cont (struct RequestHandle *handle) -{ - struct GNUNET_REST_RequestHandlerError err; - static const struct GNUNET_REST_RequestHandler handlers[] = { - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont}, - {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, - {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, - {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, - &options_cont}, - GNUNET_REST_HANDLER_END - }; - - if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, - handlers, - &err, - handle)) - { - handle->response_code = err.error_code; - GNUNET_SCHEDULER_add_now (&do_error, handle); - } -} - -/** - * If listing is enabled, prints information about the egos. - * - * This function is initially called for all egos and then again - * whenever a ego's identifier changes or if it is deleted. At the - * end of the initial pass over all egos, the function is once called - * with 'NULL' for 'ego'. That does NOT mean that the callback won't - * be invoked in the future or that there was an error. - * - * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', - * this function is only called ONCE, and 'NULL' being passed in - * 'ego' does indicate an error (i.e. name is taken or no default - * value is known). If 'ego' is non-NULL and if '*ctx' - * is set in those callbacks, the value WILL be passed to a subsequent - * call to the identity callback of 'GNUNET_IDENTITY_connect' (if - * that one was not NULL). - * - * When an identity is renamed, this function is called with the - * (known) ego but the NEW identifier. - * - * When an identity is deleted, this function is called with the - * (known) ego and "NULL" for the 'identifier'. In this case, - * the 'ego' is henceforth invalid (and the 'ctx' should also be - * cleaned up). - * - * @param cls closure - * @param ego ego handle - * @param ctx context for application to store data for this ego - * (during the lifetime of this process, initially NULL) - * @param identifier identifier assigned by the user for this ego, - * NULL if the user just deleted the ego and it - * must thus no longer be used - */ -static void -list_ego (void *cls, - struct GNUNET_IDENTITY_Ego *ego, - void **ctx, - const char *identifier) -{ - struct RequestHandle *handle = cls; - struct EgoEntry *ego_entry; - struct GNUNET_CRYPTO_EcdsaPublicKey pk; - - if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) - { - handle->state = ID_REST_STATE_POST_INIT; - init_cont (handle); - return; - } - if (ID_REST_STATE_INIT == handle->state) { - ego_entry = GNUNET_new (struct EgoEntry); - GNUNET_IDENTITY_ego_get_public_key (ego, &pk); - ego_entry->keystring = - GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); - ego_entry->ego = ego; - ego_entry->identifier = GNUNET_strdup (identifier); - GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); - } - -} - -static void -rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, - GNUNET_REST_ResultProcessor proc, - void *proc_cls) -{ - struct RequestHandle *handle = GNUNET_new (struct RequestHandle); - handle->response_code = 0; - handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; - handle->proc_cls = proc_cls; - handle->proc = proc; - handle->state = ID_REST_STATE_INIT; - handle->rest_handle = rest_handle; - - handle->url = GNUNET_strdup (rest_handle->url); - if (handle->url[strlen (handle->url)-1] == '/') - handle->url[strlen (handle->url)-1] = '\0'; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connecting...\n"); - handle->identity_handle = GNUNET_IDENTITY_connect (cfg, - &list_ego, - handle); - handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); - handle->timeout_task = - GNUNET_SCHEDULER_add_delayed (handle->timeout, - &do_timeout, - handle); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Connected\n"); -} - -/** - * Entry point for the plugin. - * - * @param cls Config info - * @return NULL on error, otherwise the plugin context - */ -void * -libgnunet_plugin_rest_reclaim_init (void *cls) -{ - static struct Plugin plugin; - struct GNUNET_REST_Plugin *api; - - cfg = cls; - if (NULL != plugin.cfg) - return NULL; /* can only initialize once! */ - memset (&plugin, 0, sizeof (struct Plugin)); - plugin.cfg = cfg; - api = GNUNET_new (struct GNUNET_REST_Plugin); - api->cls = &plugin; - api->name = GNUNET_REST_API_NS_RECLAIM; - api->process_request = &rest_identity_process_request; - GNUNET_asprintf (&allow_methods, - "%s, %s, %s, %s, %s", - MHD_HTTP_METHOD_GET, - MHD_HTTP_METHOD_POST, - MHD_HTTP_METHOD_PUT, - MHD_HTTP_METHOD_DELETE, - MHD_HTTP_METHOD_OPTIONS); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Identity Provider REST API initialized\n")); - return api; -} - - -/** - * Exit point from the plugin. - * - * @param cls the plugin context (as returned by "init") - * @return always NULL - */ -void * -libgnunet_plugin_rest_reclaim_done (void *cls) -{ - struct GNUNET_REST_Plugin *api = cls; - struct Plugin *plugin = api->cls; - plugin->cfg = NULL; - - GNUNET_free_non_null (allow_methods); - GNUNET_free (api); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Identity Provider REST plugin is finished\n"); - return NULL; -} - -/* end of plugin_rest_reclaim.c */ diff --git a/src/jsonapi/test_jsonapi.c b/src/jsonapi/test_jsonapi.c deleted file mode 100644 index 59d0bed76..000000000 --- a/src/jsonapi/test_jsonapi.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - This file is part of GNUnet - (C) 2015, 2016 GNUnet e.V. - - GNUnet is free software: you can redistribute it and/or modify it - under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, - or (at your option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - */ - -/** - * @file json/test_jsonapi.c - * @brief Tests for jsonapi conversion functions - * @author Martin Schanzenbach - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_jsonapi_lib.h" -#include "gnunet_json_lib.h" - -#define TEST_JSONAPI_DOCUMENT "{\"data\":[{\"id\":\"1\",\"type\":\"bar\",\"attributes\":{\"foo\":\"bar\"}}]}" - -#define TEST_JSONAPI_DOCUMENT_ERR "{\"errors\":[{\"id\":\"1\",\"status\":\"403\",\"code\":\"23\", \"title\":\"Error\", \"detail\":\"Error details\"}]}" - -static int -test_document_error () -{ - struct GNUNET_JSONAPI_Document *obj; - struct GNUNET_JSONAPI_Error *error; - json_t *doc_json; - json_t *data_js; - json_error_t err; - - obj = GNUNET_JSONAPI_document_new (); - error = GNUNET_JSONAPI_error_new ("1", - "403", - "23", - "Error", - "Error details", - NULL, - NULL, - NULL); - - - GNUNET_JSONAPI_document_error_add (obj, - error); - - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_document_to_json (obj, - &doc_json)); - data_js = json_loads (TEST_JSONAPI_DOCUMENT_ERR, - JSON_DECODE_ANY, - &err); - GNUNET_assert (NULL != data_js); - GNUNET_assert (0 != json_equal (data_js, doc_json)); - GNUNET_JSONAPI_document_delete (obj); - json_decref (data_js); - json_decref (doc_json); - return 0; -} - - -static int -test_document () -{ - struct GNUNET_JSONAPI_Document *obj; - struct GNUNET_JSONAPI_Resource *res; - json_t *doc_json; - json_t *data_js; - json_error_t err; - int ret; - - obj = GNUNET_JSONAPI_document_new (); - res = GNUNET_JSONAPI_resource_new ("bar", - "1"); - - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_resource_add_attr (res, - "foo", - json_string ("bar"))); - - GNUNET_JSONAPI_document_resource_add (obj, - res); - - GNUNET_assert (GNUNET_OK == - GNUNET_JSONAPI_document_to_json (obj, - &doc_json)); - data_js = json_loads (TEST_JSONAPI_DOCUMENT, - JSON_DECODE_ANY, - &err); - GNUNET_assert (NULL != data_js); - ret = json_equal (data_js, doc_json) ? 0 : 1; - GNUNET_JSONAPI_document_delete (obj); - json_decref (data_js); - json_decref (doc_json); - return ret; -} - -static int -test_serialize () -{ - struct GNUNET_JSONAPI_Document *obj; - char* tmp_data; - int ret; - json_t* data_js; - json_t* tmp_data_js; - json_error_t err; - struct GNUNET_JSON_Specification jsonapispec[] = { - GNUNET_JSON_spec_jsonapi_document (&obj), - GNUNET_JSON_spec_end() - }; - data_js = json_loads (TEST_JSONAPI_DOCUMENT, - JSON_DECODE_ANY, - &err); - GNUNET_assert (NULL != data_js); - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (data_js, jsonapispec, - NULL, NULL)); - GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_serialize (obj, - &tmp_data)); - GNUNET_JSON_parse_free (jsonapispec); - tmp_data_js = json_loads (tmp_data, JSON_DECODE_ANY, &err); - GNUNET_assert (NULL != tmp_data_js); - ret = (1 == json_equal (tmp_data_js, data_js)) ? 0 : 1; - json_decref (data_js); - json_decref (tmp_data_js); - GNUNET_free (tmp_data); - return ret; -} - -/** - * Test rsa conversions from/to JSON. - * - * @return 0 on success - */ -static int -test_spec_jsonapi () -{ - struct GNUNET_JSONAPI_Document *obj; - struct GNUNET_JSONAPI_Resource *res; - const char* data = "{\"data\":{\"id\":\"1\", \"type\":\"test\"}}"; - json_t* data_js; - json_error_t err; - - struct GNUNET_JSON_Specification jsonapispec[] = { - GNUNET_JSON_spec_jsonapi_document (&obj), - GNUNET_JSON_spec_end() - }; - data_js = json_loads (data, JSON_DECODE_ANY, &err); - GNUNET_assert (NULL != data_js); - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (data_js, jsonapispec, - NULL, NULL)); - json_decref (data_js); - res = GNUNET_JSONAPI_document_get_resource (obj, 0); - GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_id (res, "1")); - GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_type (res, "test")); - GNUNET_assert (1 == GNUNET_JSONAPI_document_resource_count (obj)); - GNUNET_JSON_parse_free (jsonapispec); - return 0; -} - - -int -main(int argc, - const char *const argv[]) -{ - GNUNET_log_setup ("test-jsonapi", - "WARNING", - NULL); - if (0 != test_spec_jsonapi ()) - return 1; - if (0 != test_serialize ()) - return 1; - if (0 != test_document ()) - return 1; - if (0 != test_document_error ()) - return 1; - return 0; -} - -/* end of test_json.c */ diff --git a/src/rest-plugins/Makefile.am b/src/rest-plugins/Makefile.am index 484dceaba..61cd7955d 100644 --- a/src/rest-plugins/Makefile.am +++ b/src/rest-plugins/Makefile.am @@ -25,9 +25,25 @@ plugin_LTLIBRARIES = \ libgnunet_plugin_rest_gns.la \ libgnunet_plugin_rest_credential.la if HAVE_ABE -plugin_LTLIBRARIES += libgnunet_plugin_rest_openid_connect.la +plugin_LTLIBRARIES += libgnunet_plugin_rest_openid_connect.la \ + libgnunet_plugin_rest_reclaim.la endif +libgnunet_plugin_rest_reclaim_la_SOURCES = \ + plugin_rest_reclaim.c \ + json_reclaim.c +libgnunet_plugin_rest_reclaim_la_LIBADD = \ + $(top_builddir)/src/identity/libgnunetidentity.la \ + $(top_builddir)/src/reclaim/libgnunetreclaim.la \ + $(top_builddir)/src/rest/libgnunetrest.la \ + $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ + $(LTLIBINTL) -ljansson -lmicrohttpd +libgnunet_plugin_rest_reclaim_la_LDFLAGS = \ + i$(GN_PLUGIN_LDFLAGS) + + libgnunet_plugin_rest_credential_la_SOURCES = \ plugin_rest_credential.c libgnunet_plugin_rest_credential_la_LIBADD = \ @@ -41,9 +57,6 @@ libgnunet_plugin_rest_credential_la_LIBADD = \ libgnunet_plugin_rest_credential_la_LDFLAGS = \ $(GN_PLUGIN_LDFLAGS) - - - libgnunet_plugin_rest_copying_la_SOURCES = \ plugin_rest_copying.c libgnunet_plugin_rest_copying_la_LIBADD = \ diff --git a/src/rest-plugins/json_reclaim.c b/src/rest-plugins/json_reclaim.c new file mode 100644 index 000000000..c0cce3be5 --- /dev/null +++ b/src/rest-plugins/json_reclaim.c @@ -0,0 +1,242 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2018 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +/** + * @file rest-plugins/json_reclaim.c + * @brief JSON handling of reclaim data + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_json_lib.h" +#include "gnunet_reclaim_service.h" +#include "gnunet_reclaim_attribute_lib.h" + +/** + * Parse given JSON object to a claim + * + * @param cls closure, NULL + * @param root the json object representing data + * @param spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_attr (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr; + const char* name_str; + const char* val_str; + const char* type_str; + const char* exp_str; + char *data; + int unpack_state; + uint32_t type; + size_t data_size; + + GNUNET_assert(NULL != root); + + if(!json_is_object(root)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error json is not array nor object!\n"); + return GNUNET_SYSERR; + } + //interpret single attribute + unpack_state = json_unpack(root, + "{s:s, s:s, s:s, s:s!}", + "name", &name_str, + "type", &type_str, + "value", &val_str, + "exp", &exp_str); + if (0 != unpack_state) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Error json object has a wrong format!\n"); + return GNUNET_SYSERR; + } + type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str); + if (GNUNET_SYSERR == (GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type, + val_str, + (void**)&data, + &data_size))) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Attribute value invalid!\n"); + return GNUNET_SYSERR; + } + attr = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str, + type, + data, + data_size); + *(struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr = attr; + return GNUNET_OK; +} + +/** + * Cleanup data left from parsing RSA public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_attr (void *cls, struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr; + attr = (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **) spec->ptr; + if (NULL != *attr) + { + GNUNET_free(*attr); + *attr = NULL; + } +} + +/** + * JSON Specification for Reclaim claims. + * + * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_attr, + .cleaner = &clean_attr, + .cls = NULL, + .field = NULL, + .ptr = attr, + .ptr_size = 0, + .size_ptr = NULL + }; + *attr = NULL; + return ret; +} +/** + * Parse given JSON object to a ticket + * + * @param cls closure, NULL + * @param root the json object representing data + * @param spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_ticket (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_RECLAIM_Ticket *ticket; + const char* rnd_str; + const char* aud_str; + const char* id_str; + int unpack_state; + + GNUNET_assert(NULL != root); + + if(!json_is_object(root)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error json is not array nor object!\n"); + return GNUNET_SYSERR; + } + //interpret single ticket + unpack_state = json_unpack(root, + "{s:s, s:s, s:s!}", + "rnd", &rnd_str, + "audience", &aud_str, + "identity", &id_str); + if (0 != unpack_state) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Error json object has a wrong format!\n"); + return GNUNET_SYSERR; + } + ticket = GNUNET_new (struct GNUNET_RECLAIM_Ticket); + if (GNUNET_OK != GNUNET_STRINGS_string_to_data (rnd_str, + strlen (rnd_str), + &ticket->rnd, + sizeof (uint64_t))) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Rnd invalid\n"); + GNUNET_free(ticket); + return GNUNET_SYSERR; + } + GNUNET_STRINGS_string_to_data (id_str, + strlen (id_str), + &ticket->identity, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Identity invalid\n"); + GNUNET_free(ticket); + return GNUNET_SYSERR; + } + + GNUNET_STRINGS_string_to_data (aud_str, + strlen (aud_str), + &ticket->audience, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Audience invalid\n"); + GNUNET_free(ticket); + return GNUNET_SYSERR; + } + + *(struct GNUNET_RECLAIM_Ticket **) spec->ptr = ticket; + return GNUNET_OK; +} + +/** + * Cleanup data left from parsing RSA public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_ticket (void *cls, struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_RECLAIM_Ticket **ticket; + ticket = (struct GNUNET_RECLAIM_Ticket **) spec->ptr; + if (NULL != *ticket) + { + GNUNET_free(*ticket); + *ticket = NULL; + } +} + +/** + * JSON Specification for Reclaim tickets. + * + * @param ticket struct of GNUNET_RECLAIM_Ticket to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_ticket, + .cleaner = &clean_ticket, + .cls = NULL, + .field = NULL, + .ptr = ticket, + .ptr_size = 0, + .size_ptr = NULL + }; + *ticket = NULL; + return ret; +} diff --git a/src/rest-plugins/json_reclaim.h b/src/rest-plugins/json_reclaim.h new file mode 100644 index 000000000..49674a173 --- /dev/null +++ b/src/rest-plugins/json_reclaim.h @@ -0,0 +1,46 @@ +/* + This file is part of GNUnet. + Copyright (C) 2009-2018 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +/** + * @file rest-plugins/json_reclaim.h + * @brief JSON handling of reclaim data + * @author Martin Schanzenbach + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_json_lib.h" +#include "gnunet_reclaim_service.h" +#include "gnunet_reclaim_attribute_lib.h" + +/** + * JSON Specification for Reclaim claims. + * + * @param ticket struct of GNUNET_RECLAIM_ATTRIBUTE_Claim to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_RECLAIM_JSON_spec_claim (struct GNUNET_RECLAIM_ATTRIBUTE_Claim **attr); + +/** + * JSON Specification for Reclaim tickets. + * + * @param ticket struct of GNUNET_RECLAIM_Ticket to fill + * @return JSON Specification + */ +struct GNUNET_JSON_Specification +GNUNET_RECLAIM_JSON_spec_ticket (struct GNUNET_RECLAIM_Ticket **ticket); diff --git a/src/rest-plugins/plugin_rest_reclaim.c b/src/rest-plugins/plugin_rest_reclaim.c new file mode 100644 index 000000000..9115a9449 --- /dev/null +++ b/src/rest-plugins/plugin_rest_reclaim.c @@ -0,0 +1,1097 @@ +/* + This file is part of GNUnet. + Copyright (C) 2012-2015 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + */ +/** + * @author Martin Schanzenbach + * @author Philippe Buschmann + * @file reclaim/plugin_rest_reclaim.c + * @brief GNUnet reclaim REST plugin + * + */ + +#include "platform.h" +#include "gnunet_rest_plugin.h" +#include "gnunet_identity_service.h" +#include "gnunet_gns_service.h" +#include "gnunet_gnsrecord_lib.h" +#include "gnunet_namestore_service.h" +#include "gnunet_rest_lib.h" +#include "gnunet_jsonapi_lib.h" +#include "gnunet_jsonapi_util.h" +#include "microhttpd.h" +#include +#include +#include "gnunet_signatures.h" +#include "gnunet_reclaim_attribute_lib.h" +#include "gnunet_reclaim_service.h" +#include "json_reclaim.h" + +/** + * REST root namespace + */ +#define GNUNET_REST_API_NS_RECLAIM "/reclaim" + +/** + * Attribute namespace + */ +#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes" + +/** + * Ticket namespace + */ +#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets" + +/** + * Revoke namespace + */ +#define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke" + +/** + * Revoke namespace + */ +#define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume" + +/** + * State while collecting all egos + */ +#define ID_REST_STATE_INIT 0 + +/** + * Done collecting egos + */ +#define ID_REST_STATE_POST_INIT 1 + +/** + * The configuration handle + */ +const struct GNUNET_CONFIGURATION_Handle *cfg; + +/** + * HTTP methods allows for this plugin + */ +static char* allow_methods; + +/** + * @brief struct returned by the initialization function of the plugin + */ +struct Plugin +{ + const struct GNUNET_CONFIGURATION_Handle *cfg; +}; + +/** + * The ego list + */ +struct EgoEntry +{ + /** + * DLL + */ + struct EgoEntry *next; + + /** + * DLL + */ + struct EgoEntry *prev; + + /** + * Ego Identifier + */ + char *identifier; + + /** + * Public key string + */ + char *keystring; + + /** + * The Ego + */ + struct GNUNET_IDENTITY_Ego *ego; +}; + + +struct RequestHandle +{ + /** + * Ego list + */ + struct EgoEntry *ego_head; + + /** + * Ego list + */ + struct EgoEntry *ego_tail; + + /** + * Selected ego + */ + struct EgoEntry *ego_entry; + + /** + * Pointer to ego private key + */ + struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key; + + /** + * The processing state + */ + int state; + + /** + * Handle to Identity service. + */ + struct GNUNET_IDENTITY_Handle *identity_handle; + + /** + * Rest connection + */ + struct GNUNET_REST_RequestHandle *rest_handle; + + /** + * Handle to NAMESTORE + */ + struct GNUNET_NAMESTORE_Handle *namestore_handle; + + /** + * Iterator for NAMESTORE + */ + struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; + + /** + * Attribute claim list + */ + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list; + + /** + * IDENTITY Operation + */ + struct GNUNET_IDENTITY_Operation *op; + + /** + * Identity Provider + */ + struct GNUNET_RECLAIM_Handle *idp; + + /** + * Idp Operation + */ + struct GNUNET_RECLAIM_Operation *idp_op; + + /** + * Attribute iterator + */ + struct GNUNET_RECLAIM_AttributeIterator *attr_it; + + /** + * Ticket iterator + */ + struct GNUNET_RECLAIM_TicketIterator *ticket_it; + + /** + * A ticket + */ + struct GNUNET_RECLAIM_Ticket ticket; + + /** + * Desired timeout for the lookup (default is no timeout). + */ + struct GNUNET_TIME_Relative timeout; + + /** + * ID of a task associated with the resolution process. + */ + struct GNUNET_SCHEDULER_Task *timeout_task; + + /** + * The plugin result processor + */ + GNUNET_REST_ResultProcessor proc; + + /** + * The closure of the result processor + */ + void *proc_cls; + + /** + * The url + */ + char *url; + + /** + * Error response message + */ + char *emsg; + + /** + * Reponse code + */ + int response_code; + + /** + * Response object + */ + json_t *resp_object; + +}; + +/** + * Cleanup lookup handle + * @param handle Handle to clean up + */ +static void +cleanup_handle (struct RequestHandle *handle) +{ + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry; + struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp; + struct EgoEntry *ego_entry; + struct EgoEntry *ego_tmp; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Cleaning up\n"); + if (NULL != handle->resp_object) + json_decref (handle->resp_object); + if (NULL != handle->timeout_task) + GNUNET_SCHEDULER_cancel (handle->timeout_task); + if (NULL != handle->identity_handle) + GNUNET_IDENTITY_disconnect (handle->identity_handle); + if (NULL != handle->attr_it) + GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); + if (NULL != handle->ticket_it) + GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); + if (NULL != handle->idp) + GNUNET_RECLAIM_disconnect (handle->idp); + if (NULL != handle->url) + GNUNET_free (handle->url); + if (NULL != handle->emsg) + GNUNET_free (handle->emsg); + if (NULL != handle->namestore_handle) + GNUNET_NAMESTORE_disconnect (handle->namestore_handle); + if ( NULL != handle->attr_list ) + { + for (claim_entry = handle->attr_list->list_head; + NULL != claim_entry;) + { + claim_tmp = claim_entry; + claim_entry = claim_entry->next; + GNUNET_free(claim_tmp->claim); + GNUNET_free(claim_tmp); + } + GNUNET_free (handle->attr_list); + } + for (ego_entry = handle->ego_head; + NULL != ego_entry;) + { + ego_tmp = ego_entry; + ego_entry = ego_entry->next; + GNUNET_free (ego_tmp->identifier); + GNUNET_free (ego_tmp->keystring); + GNUNET_free (ego_tmp); + } + if (NULL != handle->attr_it) + { + GNUNET_free(handle->attr_it); + } + GNUNET_free (handle); +} + +static void +cleanup_handle_delayed (void *cls) +{ + cleanup_handle (cls); +} + + +/** + * Task run on error, sends error message. Cleans up everything. + * + * @param cls the `struct RequestHandle` + */ +static void +do_error (void *cls) +{ + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + char *json_error; + + GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }", + handle->emsg); + if ( 0 == handle->response_code ) + { + handle->response_code = MHD_HTTP_BAD_REQUEST; + } + resp = GNUNET_REST_create_response (json_error); + MHD_add_response_header (resp, "Content-Type", "application/json"); + handle->proc (handle->proc_cls, resp, handle->response_code); + GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); + GNUNET_free (json_error); +} + + +/** + * Task run on timeout, sends error message. Cleans up everything. + * + * @param cls the `struct RequestHandle` + */ +static void +do_timeout (void *cls) +{ + struct RequestHandle *handle = cls; + + handle->timeout_task = NULL; + do_error (handle); +} + + +static void +collect_error_cb (void *cls) +{ + struct RequestHandle *handle = cls; + + do_error (handle); +} + +static void +finished_cont (void *cls, + int32_t success, + const char *emsg) +{ + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + + resp = GNUNET_REST_create_response (emsg); + if (GNUNET_OK != success) + { + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); +} + + +/** + * Return attributes for identity + * + * @param cls the request handle + */ +static void +return_response (void *cls) +{ + char* result_str; + struct RequestHandle *handle = cls; + struct MHD_Response *resp; + + result_str = json_dumps (handle->resp_object, 0); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); + resp = GNUNET_REST_create_response (result_str); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + GNUNET_free (result_str); + cleanup_handle (handle); +} + +static void +collect_finished_cb (void *cls) +{ + struct RequestHandle *handle = cls; + //Done + handle->attr_it = NULL; + handle->ticket_it = NULL; + GNUNET_SCHEDULER_add_now (&return_response, handle); +} + + +/** + * Collect all attributes for an ego + * + */ +static void +ticket_collect (void *cls, + const struct GNUNET_RECLAIM_Ticket *ticket) +{ + json_t *json_resource; + struct RequestHandle *handle = cls; + json_t *value; + char* tmp; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n"); + tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, + sizeof (uint64_t)); + json_resource = json_object (); + GNUNET_free (tmp); + json_array_append (handle->resp_object, + json_resource); + + tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + value = json_string (tmp); + json_object_set_new (json_resource, + "issuer", + value); + GNUNET_free (tmp); + json_decref (value); + tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); + value = json_string (tmp); + json_object_set_new (json_resource, + "audience", + value); + GNUNET_free (tmp); + json_decref (value); + tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd, + sizeof (uint64_t)); + value = json_string (tmp); + json_object_set_new (json_resource, + "rnd", + value); + GNUNET_free (tmp); + json_decref (value); + GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it); +} + + + +/** + * List tickets for identity request + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ +static void +list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + char *identity; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n", + handle->url); + if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >= + strlen (handle->url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1; + + for (ego_entry = handle->ego_head; + NULL != ego_entry; + ego_entry = ego_entry->next) + if (0 == strcmp (identity, ego_entry->identifier)) + break; + handle->resp_object = json_array (); + + if (NULL == ego_entry) + { + //Done + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", + identity); + GNUNET_SCHEDULER_add_now (&return_response, handle); + return; + } + priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->ticket_it = GNUNET_RECLAIM_ticket_iteration_start (handle->idp, + priv_key, + &collect_error_cb, + handle, + &ticket_collect, + handle, + &collect_finished_cb, + handle); +} + + +static void +add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + const char* identity; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute; + struct GNUNET_TIME_Relative exp; + char term_data[handle->rest_handle->data_size+1]; + json_t *data_json; + json_error_t err; + struct GNUNET_JSON_Specification attrspec[] = { + GNUNET_RECLAIM_JSON_spec_claim (&attribute), + GNUNET_JSON_spec_end() + }; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n", + handle->url); + if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= + strlen (handle->url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; + + for (ego_entry = handle->ego_head; + NULL != ego_entry; + ego_entry = ego_entry->next) + if (0 == strcmp (identity, ego_entry->identifier)) + break; + + if (NULL == ego_entry) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Identity unknown (%s)\n", identity); + return; + } + identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + + if (0 >= handle->rest_handle->data_size) + { + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + term_data[handle->rest_handle->data_size] = '\0'; + GNUNET_memcpy (term_data, + handle->rest_handle->data, + handle->rest_handle->data_size); + data_json = json_loads (term_data, + JSON_DECODE_ANY, + &err); + GNUNET_assert (GNUNET_OK == + GNUNET_JSON_parse (data_json, attrspec, + NULL, NULL)); + json_decref (data_json); + if (NULL == attribute) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse attribute from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp, + identity_priv, + attribute, + &exp, + &finished_cont, + handle); + GNUNET_JSON_parse_free (attrspec); +} + + + +/** + * Collect all attributes for an ego + * + */ +static void +attr_collect (void *cls, + const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) +{ + struct RequestHandle *handle = cls; + json_t *value; + char* tmp_value; + + if ((NULL == attr->name) || (NULL == attr->data)) + { + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", + attr->name); + + tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, + attr->data, + attr->data_size); + + value = json_string (tmp_value); + + json_object_set_new (handle->resp_object, + attr->name, + value); + json_decref (value); + GNUNET_free(tmp_value); + GNUNET_RECLAIM_get_attributes_next (handle->attr_it); +} + + + +/** + * List attributes for identity request + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ +static void +list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + char *identity; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n", + handle->url); + if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >= + strlen (handle->url)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1; + + for (ego_entry = handle->ego_head; + NULL != ego_entry; + ego_entry = ego_entry->next) + if (0 == strcmp (identity, ego_entry->identifier)) + break; + handle->resp_object = json_object (); + + + if (NULL == ego_entry) + { + //Done + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n", + identity); + GNUNET_SCHEDULER_add_now (&return_response, handle); + return; + } + priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp, + priv_key, + &collect_error_cb, + handle, + &attr_collect, + handle, + &collect_finished_cb, + handle); +} + + +static void +revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + struct GNUNET_RECLAIM_Ticket *ticket; + struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; + char term_data[handle->rest_handle->data_size+1]; + json_t *data_json; + json_error_t err; + struct GNUNET_JSON_Specification tktspec[] = { + GNUNET_RECLAIM_JSON_spec_ticket (&ticket), + GNUNET_JSON_spec_end() + }; + + if (0 >= handle->rest_handle->data_size) + { + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + term_data[handle->rest_handle->data_size] = '\0'; + GNUNET_memcpy (term_data, + handle->rest_handle->data, + handle->rest_handle->data_size); + data_json = json_loads (term_data, + JSON_DECODE_ANY, + &err); + GNUNET_assert (GNUNET_OK == + GNUNET_JSON_parse (data_json, tktspec, + NULL, NULL)); + json_decref (data_json); + if (NULL == ticket) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse ticket from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != GNUNET_JSON_parse (data_json, + tktspec, + NULL, NULL)) + { + handle->emsg = GNUNET_strdup ("Not a ticket!\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + GNUNET_JSON_parse_free (tktspec); + json_decref (data_json); + return; + } + + for (ego_entry = handle->ego_head; + NULL != ego_entry; + ego_entry = ego_entry->next) + { + GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, + &tmp_pk); + if (0 == memcmp (&ticket->identity, + &tmp_pk, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + break; + } + if (NULL == ego_entry) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Identity unknown\n"); + GNUNET_JSON_parse_free (tktspec); + return; + } + identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp, + identity_priv, + ticket, + &finished_cont, + handle); + GNUNET_JSON_parse_free (tktspec); +} + +static void +consume_cont (void *cls, + const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, + const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) +{ + struct RequestHandle *handle = cls; + char *val_str; + json_t *value; + + if (NULL == identity) + { + GNUNET_SCHEDULER_add_now (&return_response, handle); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n", + attr->name); + val_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, + attr->data, + attr->data_size); + if (NULL == val_str) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to parse value for: %s\n", + attr->name); + return; + } + value = json_string(val_str); + json_object_set_new (handle->resp_object, + attr->name, + value); + json_decref (value); + GNUNET_free (val_str); +} + +static void +consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv; + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + struct GNUNET_RECLAIM_Ticket *ticket; + struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk; + char term_data[handle->rest_handle->data_size+1]; + json_t *data_json; + json_error_t err; + struct GNUNET_JSON_Specification tktspec[] = { + GNUNET_RECLAIM_JSON_spec_ticket (&ticket), + GNUNET_JSON_spec_end () + }; + + if (0 >= handle->rest_handle->data_size) + { + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + + term_data[handle->rest_handle->data_size] = '\0'; + GNUNET_memcpy (term_data, + handle->rest_handle->data, + handle->rest_handle->data_size); + data_json = json_loads (term_data, + JSON_DECODE_ANY, + &err); + if (NULL == data_json) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unable to parse JSON Object from %s\n", + term_data); + GNUNET_SCHEDULER_add_now (&do_error, handle); + return; + } + if (GNUNET_OK != GNUNET_JSON_parse (data_json, + tktspec, + NULL, NULL)) + { + handle->emsg = GNUNET_strdup ("Not a ticket!\n"); + GNUNET_SCHEDULER_add_now (&do_error, handle); + GNUNET_JSON_parse_free(tktspec); + json_decref (data_json); + return; + } + for (ego_entry = handle->ego_head; + NULL != ego_entry; + ego_entry = ego_entry->next) + { + GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, + &tmp_pk); + if (0 == memcmp (&ticket->audience, + &tmp_pk, + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey))) + break; + } + if (NULL == ego_entry) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Identity unknown\n"); + GNUNET_JSON_parse_free (tktspec); + return; + } + identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); + handle->resp_object = json_object (); + handle->idp = GNUNET_RECLAIM_connect (cfg); + handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, + identity_priv, + ticket, + &consume_cont, + handle); + GNUNET_JSON_parse_free (tktspec); +} + + + +/** + * Respond to OPTIONS request + * + * @param con_handle the connection handle + * @param url the url + * @param cls the RequestHandle + */ +static void +options_cont (struct GNUNET_REST_RequestHandle *con_handle, + const char* url, + void *cls) +{ + struct MHD_Response *resp; + struct RequestHandle *handle = cls; + + //For now, independent of path return all options + resp = GNUNET_REST_create_response (NULL); + MHD_add_response_header (resp, + "Access-Control-Allow-Methods", + allow_methods); + handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); + cleanup_handle (handle); + return; +} + +/** + * Handle rest request + * + * @param handle the request handle + */ +static void +init_cont (struct RequestHandle *handle) +{ + struct GNUNET_REST_RequestHandlerError err; + static const struct GNUNET_REST_RequestHandler handlers[] = { + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont}, + {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont}, + {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, + {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, + {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, + {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM, + &options_cont}, + GNUNET_REST_HANDLER_END + }; + + if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, + handlers, + &err, + handle)) + { + handle->response_code = err.error_code; + GNUNET_SCHEDULER_add_now (&do_error, handle); + } +} + +/** + * If listing is enabled, prints information about the egos. + * + * This function is initially called for all egos and then again + * whenever a ego's identifier changes or if it is deleted. At the + * end of the initial pass over all egos, the function is once called + * with 'NULL' for 'ego'. That does NOT mean that the callback won't + * be invoked in the future or that there was an error. + * + * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', + * this function is only called ONCE, and 'NULL' being passed in + * 'ego' does indicate an error (i.e. name is taken or no default + * value is known). If 'ego' is non-NULL and if '*ctx' + * is set in those callbacks, the value WILL be passed to a subsequent + * call to the identity callback of 'GNUNET_IDENTITY_connect' (if + * that one was not NULL). + * + * When an identity is renamed, this function is called with the + * (known) ego but the NEW identifier. + * + * When an identity is deleted, this function is called with the + * (known) ego and "NULL" for the 'identifier'. In this case, + * the 'ego' is henceforth invalid (and the 'ctx' should also be + * cleaned up). + * + * @param cls closure + * @param ego ego handle + * @param ctx context for application to store data for this ego + * (during the lifetime of this process, initially NULL) + * @param identifier identifier assigned by the user for this ego, + * NULL if the user just deleted the ego and it + * must thus no longer be used + */ +static void +list_ego (void *cls, + struct GNUNET_IDENTITY_Ego *ego, + void **ctx, + const char *identifier) +{ + struct RequestHandle *handle = cls; + struct EgoEntry *ego_entry; + struct GNUNET_CRYPTO_EcdsaPublicKey pk; + + if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) + { + handle->state = ID_REST_STATE_POST_INIT; + init_cont (handle); + return; + } + if (ID_REST_STATE_INIT == handle->state) { + ego_entry = GNUNET_new (struct EgoEntry); + GNUNET_IDENTITY_ego_get_public_key (ego, &pk); + ego_entry->keystring = + GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); + ego_entry->ego = ego; + ego_entry->identifier = GNUNET_strdup (identifier); + GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); + } + +} + +static void +rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, + GNUNET_REST_ResultProcessor proc, + void *proc_cls) +{ + struct RequestHandle *handle = GNUNET_new (struct RequestHandle); + handle->response_code = 0; + handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; + handle->proc_cls = proc_cls; + handle->proc = proc; + handle->state = ID_REST_STATE_INIT; + handle->rest_handle = rest_handle; + + handle->url = GNUNET_strdup (rest_handle->url); + if (handle->url[strlen (handle->url)-1] == '/') + handle->url[strlen (handle->url)-1] = '\0'; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connecting...\n"); + handle->identity_handle = GNUNET_IDENTITY_connect (cfg, + &list_ego, + handle); + handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); + handle->timeout_task = + GNUNET_SCHEDULER_add_delayed (handle->timeout, + &do_timeout, + handle); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Connected\n"); +} + +/** + * Entry point for the plugin. + * + * @param cls Config info + * @return NULL on error, otherwise the plugin context + */ +void * +libgnunet_plugin_rest_reclaim_init (void *cls) +{ + static struct Plugin plugin; + struct GNUNET_REST_Plugin *api; + + cfg = cls; + if (NULL != plugin.cfg) + return NULL; /* can only initialize once! */ + memset (&plugin, 0, sizeof (struct Plugin)); + plugin.cfg = cfg; + api = GNUNET_new (struct GNUNET_REST_Plugin); + api->cls = &plugin; + api->name = GNUNET_REST_API_NS_RECLAIM; + api->process_request = &rest_identity_process_request; + GNUNET_asprintf (&allow_methods, + "%s, %s, %s, %s, %s", + MHD_HTTP_METHOD_GET, + MHD_HTTP_METHOD_POST, + MHD_HTTP_METHOD_PUT, + MHD_HTTP_METHOD_DELETE, + MHD_HTTP_METHOD_OPTIONS); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Identity Provider REST API initialized\n")); + return api; +} + + +/** + * Exit point from the plugin. + * + * @param cls the plugin context (as returned by "init") + * @return always NULL + */ +void * +libgnunet_plugin_rest_reclaim_done (void *cls) +{ + struct GNUNET_REST_Plugin *api = cls; + struct Plugin *plugin = api->cls; + plugin->cfg = NULL; + + GNUNET_free_non_null (allow_methods); + GNUNET_free (api); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Identity Provider REST plugin is finished\n"); + return NULL; +} + +/* end of plugin_rest_reclaim.c */ -- cgit v1.2.3