gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-challenger] branch master updated: implement protocol v1


From: gnunet
Subject: [taler-challenger] branch master updated: implement protocol v1
Date: Mon, 15 Apr 2024 11:10:38 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository challenger.

The following commit(s) were added to refs/heads/master by this push:
     new a0dfdff  implement protocol v1
a0dfdff is described below

commit a0dfdffe3b513b0d7791a456c5db528abd66abca
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Apr 15 11:10:34 2024 +0200

    implement protocol v1
---
 configure.ac                                |  27 ++++-
 src/challenger/challenger-httpd_authorize.c | 155 +++++++++++++++++++---------
 src/challenger/challenger-httpd_challenge.c | 150 +++++++++++++++++----------
 src/challenger/challenger-httpd_common.c    |  19 ++++
 src/challenger/challenger-httpd_common.h    |  10 ++
 src/challenger/challenger-httpd_config.c    |   5 +-
 src/challenger/challenger-httpd_solve.c     | 131 +++++++++++++++--------
 7 files changed, 347 insertions(+), 150 deletions(-)

diff --git a/configure.ac b/configure.ac
index 14e6887..c068628 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 # This configure file is in the public domain
 
 AC_PREREQ([2.69])
-AC_INIT([challenger],[0.10.1],[taler-bug@gnu.org])
+AC_INIT([challenger],[0.11.0],[taler-bug@gnu.org])
 AC_CONFIG_SRCDIR([src/challenger/challenger-httpd.c])
 AC_CONFIG_HEADERS([challenger_config.h])
 # support for non-recursive builds
@@ -76,7 +76,7 @@ AS_IF([test $libgnunetutil != 1],
 
 
 # test for postgres
-AX_LIB_POSTGRESQL([13])
+AX_LIB_POSTGRESQL([14])
 AS_IF([test "x$found_postgresql" = "xyes"],[postgres=true])
 AM_CONDITIONAL(HAVE_POSTGRESQL, test x$postgres = xtrue)
 
@@ -108,6 +108,29 @@ AC_CHECK_HEADERS([gnunet/gnunet_pq_lib.h],
 AM_CONDITIONAL(HAVE_GNUNETPQ, test x$libgnunetpq = x1)
 
 
+libtalermhd=0
+AC_MSG_CHECKING([for libtalermhd])
+AC_ARG_WITH(exchange,
+            [AS_HELP_STRING([--with-exchange=PFX], [base of Taler EXCHANGE 
installation])],
+            [AC_MSG_RESULT([given as $with_exchange])],
+            [AC_MSG_RESULT(not given)
+             with_exchange=yes])
+AS_CASE([$with_exchange],
+        [yes], [],
+        [no], [AC_MSG_ERROR([--with-exchange is required])],
+        [LDFLAGS="-L$with_exchange/lib $LDFLAGS"
+         CPPFLAGS="-I$with_exchange/include $CPPFLAGS $POSTGRESQL_CPPFLAGS"])
+
+AC_CHECK_HEADERS([taler/taler_mhd_lib.h],
+ [AC_CHECK_LIB([talermhd], [TALER_MHD_check_accept], libtalermhd=1)])
+AM_CONDITIONAL(HAVE_TALERMHD, test x$libtalermhd = x1)
+AS_IF([test $libtalermhd != 1],
+  [AC_MSG_ERROR([[
+***
+*** You need libtalermhd >= 0.10.3 (API v3) to build this program.
+*** This library is part of the GNU Taler exchange, available at
+***   https://taler.net
+*** ]])])
 
 
 # check for libmicrohttpd
diff --git a/src/challenger/challenger-httpd_authorize.c 
b/src/challenger/challenger-httpd_authorize.c
index 1ebe518..68015ac 100644
--- a/src/challenger/challenger-httpd_authorize.c
+++ b/src/challenger/challenger-httpd_authorize.c
@@ -1,6 +1,6 @@
 /*
   This file is part of Challenger
-  Copyright (C) 2023 Taler Systems SA
+  Copyright (C) 2023, 2024 Taler Systems SA
 
   Challenger 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
@@ -26,6 +26,38 @@
 #include "challenger-httpd_common.h"
 
 
+/**
+ * Generate error reply in the format requested by
+ * the client.
+ *
+ * @param hc our context
+ * @param template error template to use
+ * @param http_status HTTP status to return
+ * @param ec error code to return
+ * @param hint human-readable hint to give
+ */
+static MHD_RESULT
+reply_error (struct CH_HandlerContext *hc,
+             const char *template,
+             unsigned int http_status,
+             enum TALER_ErrorCode ec,
+             const char *hint)
+{
+  if (0 == CH_get_output_type (hc->connection))
+    return TALER_TEMPLATING_reply_error (
+      hc->connection,
+      template,
+      http_status,
+      ec,
+      hint);
+  return TALER_MHD_reply_with_error (
+    hc->connection,
+    http_status,
+    ec,
+    hint);
+}
+
+
 MHD_RESULT
 CH_handler_authorize (struct CH_HandlerContext *hc,
                       const char *upload_data,
@@ -47,10 +79,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                                      sizeof (nonce)))
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_NOT_FOUND,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       hc->path);
+    return reply_error (
+      hc,
+      "invalid-request",
+      MHD_HTTP_NOT_FOUND,
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      hc->path);
   }
   response_type
     = MHD_lookup_connection_value (hc->connection,
@@ -59,19 +93,23 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
   if (NULL == response_type)
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       "response_type");
+    return reply_error (
+      hc,
+      "invalid-request",
+      MHD_HTTP_BAD_REQUEST,
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      "response_type");
   }
   if (0 != strcmp (response_type,
                    "code"))
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                       "response_type (must be 'code')");
+    return reply_error (
+      hc,
+      "invalid-request",
+      MHD_HTTP_BAD_REQUEST,
+      TALER_EC_GENERIC_PARAMETER_MALFORMED,
+      "response_type (must be 'code')");
   }
 
   {
@@ -85,10 +123,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
     if (NULL == client_id_str)
     {
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_PARAMETER_MISSING,
-                                         "client_id");
+      return reply_error (
+        hc,
+        "invalid_request",
+        MHD_HTTP_BAD_REQUEST,
+        TALER_EC_GENERIC_PARAMETER_MISSING,
+        "client_id");
     }
     if (1 != sscanf (client_id_str,
                      "%llu%c",
@@ -96,10 +136,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                      &dummy))
     {
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                         "client_id");
+      return reply_error (
+        hc,
+        "invalid-request",
+        MHD_HTTP_BAD_REQUEST,
+        TALER_EC_GENERIC_PARAMETER_MALFORMED,
+        "client_id");
     }
   }
   redirect_uri
@@ -120,10 +162,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                       strlen ("https://";))) )
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                       "redirect_uri (has to start with 
'http://' or 'https://')");
+    return reply_error (
+      hc,
+      "invalid-request",
+      MHD_HTTP_BAD_REQUEST,
+      TALER_EC_GENERIC_PARAMETER_MALFORMED,
+      "redirect_uri (has to start with 'http://' or 'https://')");
   }
   state
     = MHD_lookup_connection_value (hc->connection,
@@ -131,6 +175,7 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                                    "state");
   if (NULL == state)
     state = "";
+
   scope
     = MHD_lookup_connection_value (hc->connection,
                                    MHD_GET_ARGUMENT_KIND,
@@ -158,11 +203,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "internal-error",
-                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                           TALER_EC_GENERIC_DB_STORE_FAILED,
-                                           "authorize_start");
+      return reply_error (
+        hc,
+        "internal-error",
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_STORE_FAILED,
+        "authorize_start");
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       return MHD_NO;
@@ -172,11 +218,12 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                   "Failed to find authorization process of client %llu for 
nonce `%s'\n",
                   client_id,
                   hc->path);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "validation-unknown",
-                                           MHD_HTTP_NOT_FOUND,
-                                           
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
-                                           NULL);
+      return reply_error (
+        hc,
+        "validation-unknown",
+        MHD_HTTP_NOT_FOUND,
+        TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
+        NULL);
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       break;
     }
@@ -221,22 +268,32 @@ CH_handler_authorize (struct CH_HandlerContext *hc,
                                  address_attempts_left)
         );
       http_status = MHD_HTTP_OK;
-      ret = TALER_TEMPLATING_build (
-        hc->connection,
-        &http_status,
-        form,
-        NULL,
-        NULL,
-        args,
-        &resp);
-      GNUNET_free (form);
-      json_decref (args);
-      if (GNUNET_SYSERR == ret)
+      if (0 == CH_get_output_type (hc->connection))
+      {
+        ret = TALER_TEMPLATING_build (
+          hc->connection,
+          &http_status,
+          form,
+          NULL,
+          NULL,
+          args,
+          &resp);
+        GNUNET_free (form);
+        json_decref (args);
+        if (GNUNET_SYSERR == ret)
+        {
+          GNUNET_break (0);
+          return MHD_NO;
+        }
+        GNUNET_break (GNUNET_OK == ret);
+      }
+      else
       {
-        GNUNET_break (0);
-        return MHD_NO;
+        GNUNET_break (0 ==
+                      json_object_del (args,
+                                       "nonce"));
+        resp = TALER_MHD_make_json_steal (args);
       }
-      GNUNET_break (GNUNET_OK == ret);
       GNUNET_break (MHD_YES ==
                     MHD_add_response_header (resp,
                                              MHD_HTTP_HEADER_CACHE_CONTROL,
diff --git a/src/challenger/challenger-httpd_challenge.c 
b/src/challenger/challenger-httpd_challenge.c
index 883ad23..c5fed98 100644
--- a/src/challenger/challenger-httpd_challenge.c
+++ b/src/challenger/challenger-httpd_challenge.c
@@ -1,6 +1,6 @@
 /*
   This file is part of Challenger
-  Copyright (C) 2023 Taler Systems SA
+  Copyright (C) 2023, 2024 Taler Systems SA
 
   Challenger 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
@@ -223,6 +223,40 @@ cleanup_ctx (void *cls)
 }
 
 
+/**
+ * Generate error reply in the format requested by
+ * the client.
+ *
+ * @param bc our context
+ * @param template error template to use
+ * @param http_status HTTP status to return
+ * @param ec error code to return
+ * @param hint human-readable hint to give
+ */
+static MHD_RESULT
+reply_error (struct ChallengeContext *bc,
+             const char *template,
+             unsigned int http_status,
+             enum TALER_ErrorCode ec,
+             const char *hint)
+{
+  struct CH_HandlerContext *hc = bc->hc;
+
+  if (0 == CH_get_output_type (hc->connection))
+    return TALER_TEMPLATING_reply_error (
+      hc->connection,
+      template,
+      http_status,
+      ec,
+      hint);
+  return TALER_MHD_reply_with_error (
+    hc->connection,
+    http_status,
+    ec,
+    hint);
+}
+
+
 /**
  * Function called when our PIN transmission helper has terminated.
  *
@@ -270,11 +304,11 @@ send_tan (struct ChallengeContext *bc)
     MHD_RESULT mres;
 
     GNUNET_break (0);
-    mres = TALER_TEMPLATING_reply_error (bc->hc->connection,
-                                         "internal-error",
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         
TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
-                                         "pipe");
+    mres = reply_error (bc,
+                        "internal-error",
+                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                        TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
+                        "pipe");
     bc->status = (MHD_YES == mres)
       ? GNUNET_NO
       : GNUNET_SYSERR;
@@ -305,11 +339,11 @@ send_tan (struct ChallengeContext *bc)
 
     GNUNET_break (0);
     GNUNET_DISK_pipe_close (p);
-    mres = TALER_TEMPLATING_reply_error (bc->hc->connection,
-                                         "internal-error",
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         
TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
-                                         "exec");
+    mres = reply_error (bc,
+                        "internal-error",
+                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                        TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
+                        "exec");
     bc->status = (MHD_YES == mres)
       ? GNUNET_NO
       : GNUNET_SYSERR;
@@ -339,11 +373,11 @@ send_tan (struct ChallengeContext *bc)
         MHD_RESULT mres;
 
         GNUNET_break (0);
-        mres = TALER_TEMPLATING_reply_error (bc->hc->connection,
-                                             "internal-error",
-                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                             
TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
-                                             "write");
+        mres = reply_error (bc,
+                            "internal-error",
+                            MHD_HTTP_INTERNAL_SERVER_ERROR,
+                            TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
+                            "write");
         GNUNET_free (msg);
         bc->status = (MHD_YES == mres)
           ? GNUNET_NO
@@ -516,11 +550,11 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
                                        sizeof (bc->nonce)))
     {
       GNUNET_break_op (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "invalid-request",
-                                           MHD_HTTP_NOT_FOUND,
-                                           TALER_EC_GENERIC_PARAMETER_MISSING,
-                                           hc->path);
+      return reply_error (bc,
+                          "invalid-request",
+                          MHD_HTTP_NOT_FOUND,
+                          TALER_EC_GENERIC_PARAMETER_MISSING,
+                          hc->path);
     }
     TALER_MHD_check_content_length (hc->connection,
                                     1024);
@@ -548,11 +582,11 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
                      "%u/%d",
                      (unsigned int) bc->exit_code,
                      bc->pst);
-    return TALER_TEMPLATING_reply_error (hc->connection,
-                                         "internal-error",
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         
TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
-                                         es);
+    return reply_error (bc,
+                        "internal-error",
+                        MHD_HTTP_INTERNAL_SERVER_ERROR,
+                        TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
+                        es);
   }
   /* handle upload */
   if (0 != *upload_data_size)
@@ -596,11 +630,11 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
     if (NULL != bad_field)
     {
       GNUNET_break_op (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "invalid-request",
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           bad_field);
+      return reply_error (bc,
+                          "invalid-request",
+                          MHD_HTTP_BAD_REQUEST,
+                          TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                          bad_field);
     }
   }
   if (! bc->db_finished)
@@ -624,21 +658,21 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "internal-error",
-                                           MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                           TALER_EC_GENERIC_DB_STORE_FAILED,
-                                           "set-address-and-pin");
+      return reply_error (bc,
+                          "internal-error",
+                          MHD_HTTP_INTERNAL_SERVER_ERROR,
+                          TALER_EC_GENERIC_DB_STORE_FAILED,
+                          "set-address-and-pin");
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       return MHD_NO;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       GNUNET_break_op (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "validation-unknown",
-                                           MHD_HTTP_NOT_FOUND,
-                                           
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
-                                           NULL);
+      return reply_error (bc,
+                          "validation-unknown",
+                          MHD_HTTP_NOT_FOUND,
+                          TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
+                          NULL);
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       break;
     }
@@ -707,20 +741,30 @@ CH_handler_challenge (struct CH_HandlerContext *hc,
                                    CH_validation_duration)))
       );
     http_status = MHD_HTTP_OK;
-    ret = TALER_TEMPLATING_build (hc->connection,
-                                  &http_status,
-                                  "enter-tan-form",
-                                  NULL,
-                                  NULL,
-                                  args,
-                                  &resp);
-    json_decref (args);
-    if (GNUNET_SYSERR == ret)
+    if (0 == CH_get_output_type (hc->connection))
     {
-      GNUNET_break (0);
-      return MHD_NO;
+      ret = TALER_TEMPLATING_build (hc->connection,
+                                    &http_status,
+                                    "enter-tan-form",
+                                    NULL,
+                                    NULL,
+                                    args,
+                                    &resp);
+      json_decref (args);
+      if (GNUNET_SYSERR == ret)
+      {
+        GNUNET_break (0);
+        return MHD_NO;
+      }
+      GNUNET_break (GNUNET_OK == ret);
+    }
+    else
+    {
+      GNUNET_break (0 ==
+                    json_object_del (args,
+                                     "nonce"));
+      resp = TALER_MHD_make_json (args);
     }
-    GNUNET_break (GNUNET_OK == ret);
     GNUNET_break (MHD_YES ==
                   MHD_add_response_header (resp,
                                            MHD_HTTP_HEADER_CACHE_CONTROL,
diff --git a/src/challenger/challenger-httpd_common.c 
b/src/challenger/challenger-httpd_common.c
index d976715..65fbfa5 100644
--- a/src/challenger/challenger-httpd_common.c
+++ b/src/challenger/challenger-httpd_common.c
@@ -24,6 +24,25 @@
 
 #define RFC_8959_PREFIX "secret-token:"
 
+
+int
+CH_get_output_type (struct MHD_Connection *connection)
+{
+  int output_type;
+
+  output_type
+    = TALER_MHD_check_accept (connection,
+                              MHD_HTTP_HEADER_ACCEPT,
+                              "text/html",
+                              "application/json",
+                              NULL);
+  if (output_type < 0)
+    output_type = 0; /* default to HTML */
+  GNUNET_assert (output_type < 2);
+  return output_type;
+}
+
+
 const char *
 CH_get_client_secret (struct MHD_Connection *connection)
 {
diff --git a/src/challenger/challenger-httpd_common.h 
b/src/challenger/challenger-httpd_common.h
index d37e4e3..8b1a3d2 100644
--- a/src/challenger/challenger-httpd_common.h
+++ b/src/challenger/challenger-httpd_common.h
@@ -34,6 +34,16 @@ const char *
 CH_get_client_secret (struct MHD_Connection *connection);
 
 
+/**
+ * Return desired output format.
+ *
+ * @param connection connection to check
+ * @return 0 for HTML and 1 for JSON.
+ */
+int
+CH_get_output_type (struct MHD_Connection *connection);
+
+
 /**
  * Compute code that would grant access to the ``/token``
  * endpoint to obtain an access token for a particular
diff --git a/src/challenger/challenger-httpd_config.c 
b/src/challenger/challenger-httpd_config.c
index c772eac..fcbaf15 100644
--- a/src/challenger/challenger-httpd_config.c
+++ b/src/challenger/challenger-httpd_config.c
@@ -1,6 +1,6 @@
 /*
   This file is part of Challenger
-  Copyright (C) 2023 Taler Systems SA
+  Copyright (C) 2023, 2024 Taler Systems SA
 
   Challenger is free software; you can redistribute it and/or modify it under 
the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -27,6 +27,7 @@
  * Protocol version history:
  *
  * 0: original design
+ * 1: revision to support SPA
  */
 
 
@@ -45,7 +46,7 @@ CH_handler_config (struct CH_HandlerContext *hc,
     GNUNET_JSON_pack_string ("name",
                              "challenger"),
     GNUNET_JSON_pack_string ("version",
-                             "0:1:0"));
+                             "1:0:1"));
 }
 
 
diff --git a/src/challenger/challenger-httpd_solve.c 
b/src/challenger/challenger-httpd_solve.c
index 0bde4b3..15495bb 100644
--- a/src/challenger/challenger-httpd_solve.c
+++ b/src/challenger/challenger-httpd_solve.c
@@ -1,6 +1,6 @@
 /*
   This file is part of Challenger
-  Copyright (C) 2023 Taler Systems SA
+  Copyright (C) 2023, 2024 Taler Systems SA
 
   Challenger 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
@@ -40,6 +40,11 @@ struct SolveContext
    */
   struct CHALLENGER_ValidationNonceP nonce;
 
+  /**
+   * HTTP request context.
+   */
+  struct CH_HandlerContext *hc;
+
   /**
    * Handle for processing uploaded data.
    */
@@ -105,6 +110,40 @@ cleanup_ctx (void *cls)
 }
 
 
+/**
+ * Generate error reply in the format requested by
+ * the client.
+ *
+ * @param bc our context
+ * @param template error template to use
+ * @param http_status HTTP status to return
+ * @param ec error code to return
+ * @param hint human-readable hint to give
+ */
+static MHD_RESULT
+reply_error (struct SolveContext *bc,
+             const char *template,
+             unsigned int http_status,
+             enum TALER_ErrorCode ec,
+             const char *hint)
+{
+  struct CH_HandlerContext *hc = bc->hc;
+
+  if (0 == CH_get_output_type (hc->connection))
+    return TALER_TEMPLATING_reply_error (
+      hc->connection,
+      template,
+      http_status,
+      ec,
+      hint);
+  return TALER_MHD_reply_with_error (
+    hc->connection,
+    http_status,
+    ec,
+    hint);
+}
+
+
 /**
  * Iterator over key-value pairs where the value may be made available
  * in increments and/or may not be zero-terminated.  Used for
@@ -169,6 +208,7 @@ CH_handler_solve (struct CH_HandlerContext *hc,
     bc = GNUNET_new (struct SolveContext);
     hc->cc = &cleanup_ctx;
     hc->ctx = bc;
+    bc->hc = hc;
     bc->pp = MHD_create_post_processor (hc->connection,
                                         1024,
                                         &post_iter,
@@ -180,11 +220,11 @@ CH_handler_solve (struct CH_HandlerContext *hc,
                                        sizeof (bc->nonce)))
     {
       GNUNET_break_op (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "invalid-request",
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
-                                           hc->path);
+      return reply_error (bc,
+                          "invalid-request",
+                          MHD_HTTP_BAD_REQUEST,
+                          TALER_EC_CHALLENGER_HELPER_EXEC_FAILED,
+                          hc->path);
     }
     TALER_MHD_check_content_length (hc->connection,
                                     1024);
@@ -206,11 +246,11 @@ CH_handler_solve (struct CH_HandlerContext *hc,
   if (NULL == bc->pin)
   {
     GNUNET_break_op (0);
-    return TALER_TEMPLATING_reply_error (hc->connection,
-                                         "invalid-request",
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_PARAMETER_MISSING,
-                                         "pin");
+    return reply_error (bc,
+                        "invalid-request",
+                        MHD_HTTP_BAD_REQUEST,
+                        TALER_EC_GENERIC_PARAMETER_MISSING,
+                        "pin");
   }
   {
     unsigned int pin;
@@ -226,11 +266,11 @@ CH_handler_solve (struct CH_HandlerContext *hc,
                      &dummy))
     {
       GNUNET_break_op (0);
-      return TALER_TEMPLATING_reply_error (hc->connection,
-                                           "invalid-request",
-                                           MHD_HTTP_BAD_REQUEST,
-                                           
TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                           "pin");
+      return reply_error (bc,
+                          "invalid-request",
+                          MHD_HTTP_BAD_REQUEST,
+                          TALER_EC_GENERIC_PARAMETER_MALFORMED,
+                          "pin");
     }
 
     qs = CH_db->validate_solve_pin (CH_db->cls,
@@ -247,8 +287,8 @@ CH_handler_solve (struct CH_HandlerContext *hc,
     switch (qs)
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
-      return TALER_TEMPLATING_reply_error (
-        hc->connection,
+      return reply_error (
+        bc,
         "internal-error",
         MHD_HTTP_INTERNAL_SERVER_ERROR,
         TALER_EC_GENERIC_DB_FETCH_FAILED,
@@ -257,8 +297,8 @@ CH_handler_solve (struct CH_HandlerContext *hc,
       GNUNET_break (0);
       return MHD_NO;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-      return TALER_TEMPLATING_reply_error (
-        hc->connection,
+      return reply_error (
+        bc,
         "validation-unknown",
         MHD_HTTP_NOT_FOUND,
         TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
@@ -287,28 +327,31 @@ CH_handler_solve (struct CH_HandlerContext *hc,
       }
 
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                  "Invalid PIN supplied, client has chance to solve it 
again\n");
+                  "Invalid PIN supplied\n");
       details = GNUNET_JSON_PACK (
         TALER_JSON_pack_ec (TALER_EC_CHALLENGER_INVALID_PIN),
-        GNUNET_JSON_pack_bool ("exhausted",
-                               exhausted),
-        GNUNET_JSON_pack_bool ("no_challenge",
-                               no_challenge),
-        GNUNET_JSON_pack_uint64 ("addresses_left",
-                                 bc->addr_left),
         GNUNET_JSON_pack_uint64 ("addresses_left",
                                  bc->addr_left),
         GNUNET_JSON_pack_uint64 ("pin_transmissions_left",
                                  bc->pin_transmissions_left),
         GNUNET_JSON_pack_uint64 ("auth_attempts_left",
-                                 bc->auth_attempts_left)
+                                 bc->auth_attempts_left),
+        GNUNET_JSON_pack_bool ("exhausted",
+                               exhausted),
+        GNUNET_JSON_pack_bool ("no_challenge",
+                               no_challenge)
         );
-      ret = TALER_TEMPLATING_reply (hc->connection,
-                                    MHD_HTTP_FORBIDDEN,
-                                    "invalid-pin",
-                                    NULL,
-                                    NULL,
-                                    details);
+      if (0 == CH_get_output_type (hc->connection))
+        ret = TALER_TEMPLATING_reply (hc->connection,
+                                      MHD_HTTP_FORBIDDEN,
+                                      "invalid-pin",
+                                      NULL,
+                                      NULL,
+                                      details);
+      else
+        ret = TALER_MHD_reply_json (hc->connection,
+                                    details,
+                                    MHD_HTTP_FORBIDDEN);
       json_decref (details);
       return ret;
     }
@@ -337,20 +380,20 @@ CH_handler_solve (struct CH_HandlerContext *hc,
       {
       case GNUNET_DB_STATUS_HARD_ERROR:
         GNUNET_break (0);
-        return TALER_TEMPLATING_reply_error (hc->connection,
-                                             "internal-server-error",
-                                             MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                             TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                             "validation_get");
+        return reply_error (bc,
+                            "internal-server-error",
+                            MHD_HTTP_INTERNAL_SERVER_ERROR,
+                            TALER_EC_GENERIC_DB_FETCH_FAILED,
+                            "validation_get");
       case GNUNET_DB_STATUS_SOFT_ERROR:
         GNUNET_break (0);
         return MHD_NO;
       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
-        return TALER_TEMPLATING_reply_error (hc->connection,
-                                             "validation-unknown",
-                                             MHD_HTTP_NOT_FOUND,
-                                             
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
-                                             NULL);
+        return reply_error (bc,
+                            "validation-unknown",
+                            MHD_HTTP_NOT_FOUND,
+                            TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
+                            NULL);
       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
         break;
       }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]