diff options
| author | Christian Grothoff <christian@grothoff.org> | 2020-12-01 00:34:04 +0100 | 
|---|---|---|
| committer | Christian Grothoff <christian@grothoff.org> | 2020-12-01 00:34:04 +0100 | 
| commit | 65915731a93a3057bb1844187b1aa3b476c4bd42 (patch) | |
| tree | bab0eec9509240da65a77ec0ecdc41000cc4e4be /src | |
| parent | 862054f6f2e9a08ccc051343d0dacde992ea1611 (diff) | |
add dispatching logic for (most) of the new endpoints
Diffstat (limited to 'src')
| -rw-r--r-- | src/exchange/taler-exchange-httpd.c | 316 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd.h | 6 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_auditors.c | 4 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_auditors.h | 2 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_management.h | 11 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_management_auditors.c | 1 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c | 10 | ||||
| -rw-r--r-- | src/exchange/taler-exchange-httpd_management_post_keys.c | 1 | 
8 files changed, 316 insertions, 35 deletions
| diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c index 6dc68984..4896c8d4 100644 --- a/src/exchange/taler-exchange-httpd.c +++ b/src/exchange/taler-exchange-httpd.c @@ -28,20 +28,22 @@  #include <pthread.h>  #include <sys/resource.h>  #include "taler_mhd_lib.h" -#include "taler-exchange-httpd_mhd.h" +#include "taler-exchange-httpd_auditors.h"  #include "taler-exchange-httpd_deposit.h" -#include "taler-exchange-httpd_refund.h" -#include "taler-exchange-httpd_reserves_get.h" -#include "taler-exchange-httpd_withdraw.h" -#include "taler-exchange-httpd_recoup.h" +#include "taler-exchange-httpd_deposits_get.h" +#include "taler-exchange-httpd_keystate.h"  #include "taler-exchange-httpd_link.h" +#include "taler-exchange-httpd_management.h"  #include "taler-exchange-httpd_melt.h" +#include "taler-exchange-httpd_mhd.h" +#include "taler-exchange-httpd_recoup.h"  #include "taler-exchange-httpd_refreshes_reveal.h" +#include "taler-exchange-httpd_refund.h" +#include "taler-exchange-httpd_reserves_get.h"  #include "taler-exchange-httpd_terms.h"  #include "taler-exchange-httpd_transfers_get.h" -#include "taler-exchange-httpd_deposits_get.h" -#include "taler-exchange-httpd_keystate.h"  #include "taler-exchange-httpd_wire.h" +#include "taler-exchange-httpd_withdraw.h"  #include "taler_exchangedb_plugin.h"  #include <gnunet/gnunet_mhd_compat.h> @@ -178,6 +180,24 @@ typedef MHD_RESULT  /** + * Generate a 404 "not found" reply on @a connection with + * the hint @a details. + * + * @param connection where to send the reply on + * @param details details for the error message, can be NULL + */ +static MHD_RESULT +r404 (struct MHD_Connection *connection, +      const char *details) +{ +  return TALER_MHD_reply_with_error (connection, +                                     MHD_HTTP_NOT_FOUND, +                                     TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, +                                     details); +} + + +/**   * Handle a "/coins/$COIN_PUB/$OP" POST request.  Parses the "coin_pub"   * EdDSA key of the coin and demultiplexes based on $OP.   * @@ -249,10 +269,7 @@ handle_post_coins (const struct TEH_RequestHandler *rh,        return h[i].handler (connection,                             &coin_pub,                             root); -  return TALER_MHD_reply_with_error (connection, -                                     MHD_HTTP_NOT_FOUND, -                                     TALER_EC_EXCHANGE_GENERIC_OPERATION_UNKNOWN, -                                     args[1]); +  return r404 (connection, args[1]);  } @@ -367,6 +384,7 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,      char d[ulen];      /* Parse command-line arguments, if applicable */ +    args[0] = NULL;      if (rh->nargs > 0)      {        unsigned int i; @@ -384,9 +402,10 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,          args[i++] = strtok_r (NULL, "/", &sp);        /* make sure above loop ran nicely until completion, and also           that there is no excess data in 'd' afterwards */ -      if ( (i != rh->nargs) || -           (NULL == args[i - 1]) || -           (NULL != (fin = strtok_r (NULL, "/", &sp))) ) +      if ( (! rh->nargs_is_upper_bound) && +           ( (i != rh->nargs) || +             (NULL == args[i - 1]) || +             (NULL != (fin = strtok_r (NULL, "/", &sp))) ) )        {          char emsg[128 + 512]; @@ -407,12 +426,12 @@ proceed_with_handler (const struct TEH_RequestHandler *rh,                                             TALER_EC_EXCHANGE_GENERIC_WRONG_NUMBER_OF_SEGMENTS,                                             emsg);        } + +      /* just to be safe(r), we always terminate the array with a NULL +         (even if handlers requested precise number of arguments) */ +      args[i] = NULL;      } -    /* just to be safe(r), we always terminate the array with a NULL -       (which handlers should not read, but at least if they do, they'll -       crash pretty reliably...) */ -    args[rh->nargs] = NULL;      /* Above logic ensures that 'root' is exactly non-NULL for POST operations,         so we test for 'root' to decide which handler to invoke. */ @@ -473,6 +492,244 @@ handler_seed (const struct TEH_RequestHandler *rh,  /** + * Handle POST "/management/..." requests. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param root uploaded JSON data + * @param args array of additional options + * @return MHD result code + */ +static MHD_RESULT +handle_post_management (const struct TEH_RequestHandler *rh, +                        struct MHD_Connection *connection, +                        const json_t *root, +                        const char *const args[]) +{ +  if (NULL == args[0]) +  { +    GNUNET_break_op (0); +    return r404 (connection, "/management"); +  } +  if (0 == strcmp (args[0], +                   "auditors")) +  { +    struct TALER_AuditorPublicKeyP auditor_pub; + +    if (NULL == args[1]) +      return TEH_handler_management_auditors (connection, +                                              root); +    if ( (NULL == args[1]) || +         (NULL == args[2]) || +         (0 != strcmp (args[2], +                       "disable")) || +         (NULL != args[3]) ) +      return r404 (connection, +                   "/management/auditors/$AUDITOR_PUB/disable"); +    if (GNUNET_OK != +        GNUNET_STRINGS_string_to_data (args[1], +                                       strlen (args[1]), +                                       &auditor_pub, +                                       sizeof (auditor_pub))) +    { +      GNUNET_break_op (0); +      return TALER_MHD_reply_with_error (connection, +                                         MHD_HTTP_BAD_REQUEST, +                                         TALER_EC_GENERIC_PARAMETER_MALFORMED, +                                         args[1]); +    } +    return TEH_handler_management_auditors_AP_disable (connection, +                                                       &auditor_pub, +                                                       root); +  } +  if (0 == strcmp (args[0], +                   "denominations")) +  { +    struct GNUNET_HashCode h_denom_pub; + +    if ( (NULL == args[0]) || +         (NULL == args[1]) || +         (NULL == args[2]) || +         (0 != strcmp (args[2], +                       "revoke")) || +         (NULL != args[3]) ) +      return r404 (connection, +                   "/management/denominations/$HDP/revoke"); +    if (GNUNET_OK != +        GNUNET_STRINGS_string_to_data (args[2], +                                       strlen (args[2]), +                                       &h_denom_pub, +                                       sizeof (h_denom_pub))) +    { +      GNUNET_break_op (0); +      return TALER_MHD_reply_with_error (connection, +                                         MHD_HTTP_BAD_REQUEST, +                                         TALER_EC_GENERIC_PARAMETER_MALFORMED, +                                         args[2]); +    } +    return TEH_handler_management_denominations_HDP_revoke (connection, +                                                            &h_denom_pub, +                                                            root); +  } +  if (0 == strcmp (args[0], +                   "signkeys")) +  { +    struct TALER_ExchangePublicKeyP exchange_pub; + +    if ( (NULL == args[0]) || +         (NULL == args[1]) || +         (NULL == args[2]) || +         (0 != strcmp (args[2], +                       "revoke")) || +         (NULL != args[3]) ) +      return r404 (connection, +                   "/management/signkeys/$HDP/revoke"); +    if (GNUNET_OK != +        GNUNET_STRINGS_string_to_data (args[2], +                                       strlen (args[2]), +                                       &exchange_pub, +                                       sizeof (exchange_pub))) +    { +      GNUNET_break_op (0); +      return TALER_MHD_reply_with_error (connection, +                                         MHD_HTTP_BAD_REQUEST, +                                         TALER_EC_GENERIC_PARAMETER_MALFORMED, +                                         args[2]); +    } +    return TEH_handler_management_signkeys_EP_revoke (connection, +                                                      &exchange_pub, +                                                      root); +  } +#if FIXME +  /* not yet implemented! */ +  if (0 == strcmp (args[0], +                   "keys")) +  { +    if (NULL != args[1]) +    { +      GNUNET_break_op (0); +      return r404 (connection, "/management/keys/*"); +    } +    return TEH_handler_management_post_keys (connection, +                                             root); +  } +#endif +  if (0 == strcmp (args[0], +                   "wire")) +  { +    if (NULL == args[1]) +      return TEH_handler_management_denominations_wire (connection, +                                                        root); +    if ( (0 != strcmp (args[1], +                       "disable")) || +         (NULL != args[2]) ) +    { +      GNUNET_break_op (0); +      return r404 (connection, "/management/wire/disable"); +    } +    return TEH_handler_management_denominations_wire_disable (connection, +                                                              root); +  } +  if (0 == strcmp (args[0], +                   "wire-fees")) +  { +    if (NULL != args[1]) +    { +      GNUNET_break_op (0); +      return r404 (connection, "/management/wire-fees/*"); +    } +    return TEH_handler_management_post_wire_fees (connection, +                                                  root); +  } +  GNUNET_break_op (0); +  return r404 (connection, "/management/*"); +} + + +/** + * Handle a get "/management" request. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param args array of additional options (must be empty for this function) + * @return MHD result code + */ +static MHD_RESULT +handle_get_management (const struct TEH_RequestHandler *rh, +                       struct MHD_Connection *connection, +                       const char *const args[1]) +{ +  if ( (NULL == args[0]) || +       (0 != strcmp (args[0], +                     "keys")) || +       (NULL != args[1]) ) +  { +    GNUNET_break_op (0); +    return r404 (connection, "/management/*"); +  } +  GNUNET_break (0); // not implemented +  return MHD_NO; +} + + +/** + * Handle POST "/auditors/..." requests. + * + * @param rh context of the handler + * @param connection the MHD connection to handle + * @param root uploaded JSON data + * @param args array of additional options + * @return MHD result code + */ +static MHD_RESULT +handle_post_auditors (const struct TEH_RequestHandler *rh, +                      struct MHD_Connection *connection, +                      const json_t *root, +                      const char *const args[]) +{ +  struct TALER_AuditorPublicKeyP auditor_pub; +  struct GNUNET_HashCode h_denom_pub; + +  if ( (NULL == args[0]) || +       (NULL == args[1]) || +       (NULL != args[0]) ) +  { +    GNUNET_break_op (0); +    return r404 (connection, "/auditors/$AUDITOR_PUB/$H_DENOM_PUB"); +  } + +  if (GNUNET_OK != +      GNUNET_STRINGS_string_to_data (args[0], +                                     strlen (args[0]), +                                     &auditor_pub, +                                     sizeof (auditor_pub))) +  { +    GNUNET_break_op (0); +    return TALER_MHD_reply_with_error (connection, +                                       MHD_HTTP_BAD_REQUEST, +                                       TALER_EC_GENERIC_PARAMETER_MALFORMED, +                                       args[0]); +  } +  if (GNUNET_OK != +      GNUNET_STRINGS_string_to_data (args[1], +                                     strlen (args[1]), +                                     &h_denom_pub, +                                     sizeof (h_denom_pub))) +  { +    GNUNET_break_op (0); +    return TALER_MHD_reply_with_error (connection, +                                       MHD_HTTP_BAD_REQUEST, +                                       TALER_EC_GENERIC_PARAMETER_MALFORMED, +                                       args[1]); +  } +  return TEH_handler_auditors (connection, +                               &auditor_pub, +                               &h_denom_pub, +                               root); +} + + +/**   * Handle incoming HTTP request.   *   * @param cls closure for MHD daemon (unused) @@ -600,6 +857,29 @@ handle_mhd_request (void *cls,        .handler.get = &TEH_handler_deposits_get,        .nargs = 4      }, +    /* POST management endpoints */ +    { +      .url = "management", +      .method = MHD_HTTP_METHOD_POST, +      .handler.post = &handle_post_management, +      .nargs = 4, +      .nargs_is_upper_bound = true +    }, +    /* GET management endpoints (we only really have "/management/keys") */ +    { +      .url = "management", +      .method = MHD_HTTP_METHOD_GET, +      .handler.get = &handle_get_management, +      .nargs = 1 +    }, +    /* auditor endpoints */ +    { +      .url = "auditors", +      .method = MHD_HTTP_METHOD_POST, +      .handler.post = &handle_post_auditors, +      .nargs = 4, +      .nargs_is_upper_bound = true +    },      /* mark end of list */      {        .url = NULL diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h index ad46788c..5e773816 100644 --- a/src/exchange/taler-exchange-httpd.h +++ b/src/exchange/taler-exchange-httpd.h @@ -134,6 +134,12 @@ struct TEH_RequestHandler    unsigned int nargs;    /** +   * Is the number of arguments given in @e nargs only an upper bound, +   * and calling with fewer arguments could be OK? +   */ +  bool nargs_is_upper_bound; + +  /**     * Mime type to use in reply (hint, can be NULL).     */    const char *mime_type; diff --git a/src/exchange/taler-exchange-httpd_auditors.c b/src/exchange/taler-exchange-httpd_auditors.c index 60c633cf..f0fbb7eb 100644 --- a/src/exchange/taler-exchange-httpd_auditors.c +++ b/src/exchange/taler-exchange-httpd_auditors.c @@ -209,7 +209,7 @@ add_auditor_denom_sig (void *cls,  MHD_RESULT -TEH_handler_management_denominations_auditors ( +TEH_handler_auditors (    struct MHD_Connection *connection,    const struct TALER_AuditorPublicKeyP *auditor_pub,    const struct GNUNET_HashCode *h_denom_pub, @@ -255,4 +255,4 @@ TEH_handler_management_denominations_auditors (  } -/* end of taler-exchange-httpd_management_auditors.c */ +/* end of taler-exchange-httpd_auditors.c */ diff --git a/src/exchange/taler-exchange-httpd_auditors.h b/src/exchange/taler-exchange-httpd_auditors.h index de180587..f8191f8a 100644 --- a/src/exchange/taler-exchange-httpd_auditors.h +++ b/src/exchange/taler-exchange-httpd_auditors.h @@ -36,7 +36,7 @@   * @return MHD result code   */  MHD_RESULT -TEH_handler_management_denominations_auditors ( +TEH_handler_auditors (    struct MHD_Connection *connection,    const struct TALER_AuditorPublicKeyP *auditor_pub,    const struct GNUNET_HashCode *h_denom_pub, diff --git a/src/exchange/taler-exchange-httpd_management.h b/src/exchange/taler-exchange-httpd_management.h index cd5c5d8a..b5ab8478 100644 --- a/src/exchange/taler-exchange-httpd_management.h +++ b/src/exchange/taler-exchange-httpd_management.h @@ -29,14 +29,12 @@   * Handle a "/management/auditors" request.   *   * @param connection the MHD connection to handle - * @param h_denom_pub hash of the public key of the denomination to revoke   * @param root uploaded JSON data   * @return MHD result code   */  MHD_RESULT  TEH_handler_management_auditors (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub,    const json_t *root); @@ -44,14 +42,14 @@ TEH_handler_management_auditors (   * Handle a "/management/auditors/$AUDITOR_PUB/disable" request.   *   * @param connection the MHD connection to handle - * @param h_denom_pub hash of the public key of the denomination to revoke + * @param auditor_pub public key of the auditor to disable   * @param root uploaded JSON data   * @return MHD result code   */  MHD_RESULT  TEH_handler_management_auditors_AP_disable (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub, +  const struct TALER_AuditorPublicKeyP *auditor_pub,    const json_t *root); @@ -89,16 +87,15 @@ TEH_handler_management_signkeys_EP_revoke (   * Handle a POST "/management/keys" request.   *   * @param connection the MHD connection to handle - * @param h_denom_pub hash of the public key of the denomination to revoke   * @param root uploaded JSON data   * @return MHD result code   */  MHD_RESULT  TEH_handler_management_post_keys (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub,    const json_t *root); +  /**   * Handle a "/management/wire" request.   * @@ -113,7 +110,7 @@ TEH_handler_management_denominations_wire (  /** - * Handle a "/management/wire" request. + * Handle a "/management/wire/disable" request.   *   * @param connection the MHD connection to handle   * @param root uploaded JSON data diff --git a/src/exchange/taler-exchange-httpd_management_auditors.c b/src/exchange/taler-exchange-httpd_management_auditors.c index 02e4d4fa..33f1c6df 100644 --- a/src/exchange/taler-exchange-httpd_management_auditors.c +++ b/src/exchange/taler-exchange-httpd_management_auditors.c @@ -145,7 +145,6 @@ add_auditor (void *cls,  MHD_RESULT  TEH_handler_management_auditors (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub,    const json_t *root)  {    struct AddAuditorContext aac; diff --git a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c index 8904b444..e360c1a5 100644 --- a/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c +++ b/src/exchange/taler-exchange-httpd_management_auditors_AP_disable.c @@ -137,16 +137,16 @@ del_auditor (void *cls,  MHD_RESULT  TEH_handler_management_auditors_AP_disable (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub, +  const struct TALER_AuditorPublicKeyP *auditor_pub,    const json_t *root)  {    struct TALER_MasterSignatureP master_sig; -  struct DelAuditorContext dac; +  struct DelAuditorContext dac = { +    .auditor_pub = *auditor_pub +  };    struct GNUNET_JSON_Specification spec[] = {      GNUNET_JSON_spec_fixed_auto ("master_sig",                                   &master_sig), -    GNUNET_JSON_spec_fixed_auto ("auditor_pub", -                                 &dac.auditor_pub),      TALER_JSON_spec_absolute_time ("validity_end",                                     &dac.validity_end),      GNUNET_JSON_spec_end () @@ -171,7 +171,7 @@ TEH_handler_management_auditors_AP_disable (          TALER_SIGNATURE_MASTER_DEL_AUDITOR),        .purpose.size = htonl (sizeof (da)),        .end_date = GNUNET_TIME_absolute_hton (dac.validity_end), -      .auditor_pub = dac.auditor_pub +      .auditor_pub = *auditor_pub      };      if (GNUNET_OK != diff --git a/src/exchange/taler-exchange-httpd_management_post_keys.c b/src/exchange/taler-exchange-httpd_management_post_keys.c index ab4399bd..2ac69a1d 100644 --- a/src/exchange/taler-exchange-httpd_management_post_keys.c +++ b/src/exchange/taler-exchange-httpd_management_post_keys.c @@ -323,7 +323,6 @@ add_keys (void *cls,  MHD_RESULT  TEH_handler_management_post_keys (    struct MHD_Connection *connection, -  const struct GNUNET_HashCode *h_denom_pub,    const json_t *root)  {    struct AddKeysContext akc; | 
