anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_truth_challenge.c (9495B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2020, 2022 Anastasis SARL
      4 
      5   Anastasis is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file testing/testing_api_cmd_truth_challenge.c
     18  * @brief Testing of Implementation of the /truth GET
     19  * @author Christian Grothoff
     20  * @author Dennis Neufeld
     21  * @author Dominik Meister
     22  */
     23 
     24 #include "platform.h"
     25 #include "anastasis_testing_lib.h"
     26 #include <taler/taler_util.h>
     27 #include <taler/taler_testing_lib.h>
     28 #include <taler/taler_merchant_service.h>
     29 
     30 
     31 /**
     32  * State for a "keyshare lookup" CMD.
     33  */
     34 struct TruthChallengeState
     35 {
     36   /**
     37    * The interpreter state.
     38    */
     39   struct TALER_TESTING_Interpreter *is;
     40 
     41   /**
     42    * URL of the anastasis backend.
     43    */
     44   const char *anastasis_url;
     45 
     46   /**
     47    * Expected HTTP status code.
     48    */
     49   unsigned int expected_http_status;
     50 
     51   /**
     52    * The /truth GET operation handle.
     53    */
     54   struct ANASTASIS_TruthChallengeOperation *tco;
     55 
     56   /**
     57    * Reference to upload command we expect to lookup.
     58    */
     59   const char *upload_reference;
     60 
     61   /**
     62    * Reference to upload command we expect to lookup.
     63    */
     64   const char *payment_reference;
     65 
     66   /**
     67    * Payment secret requested by the service, if any.
     68    */
     69   struct ANASTASIS_PaymentSecretP payment_secret_response;
     70 
     71   /**
     72    * Taler-URI with payment request, if any.
     73    */
     74   char *pay_uri;
     75 
     76   /**
     77    * Order ID for payment request, if any.
     78    */
     79   char *order_id;
     80 
     81   /**
     82    * "code" returned by service, if any.
     83    */
     84   char *code;
     85 
     86   /**
     87    * "instructions" for how to solve the challenge as returned by service, if any.
     88    */
     89   char *instructions;
     90 
     91 };
     92 
     93 
     94 static void
     95 truth_challenge_cb (void *cls,
     96                     const struct ANASTASIS_TruthChallengeDetails *tcd)
     97 {
     98   struct TruthChallengeState *ksls = cls;
     99 
    100   ksls->tco = NULL;
    101   if (tcd->http_status != ksls->expected_http_status)
    102   {
    103     TALER_TESTING_unexpected_status (ksls->is,
    104                                      tcd->http_status,
    105                                      ksls->expected_http_status);
    106     return;
    107   }
    108   switch (tcd->http_status)
    109   {
    110   case MHD_HTTP_OK:
    111     switch (tcd->details.success.cs)
    112     {
    113     case ANASTASIS_CS_FILE_WRITTEN:
    114       {
    115         FILE *file;
    116         char code[22];
    117 
    118         file = fopen (tcd->details.success.details.challenge_filename,
    119                       "r");
    120         if (NULL == file)
    121         {
    122           GNUNET_log_strerror_file (
    123             GNUNET_ERROR_TYPE_ERROR,
    124             "open",
    125             tcd->details.success.details.challenge_filename);
    126           TALER_TESTING_interpreter_fail (ksls->is);
    127           return;
    128         }
    129         if (0 == fscanf (file,
    130                          "%21s",
    131                          code))
    132         {
    133           GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
    134                                     "fscanf",
    135                                     tcd->details.success.details.
    136                                     challenge_filename);
    137           GNUNET_break (0 == fclose (file));
    138           TALER_TESTING_interpreter_fail (ksls->is);
    139           return;
    140         }
    141         GNUNET_break (0 == fclose (file));
    142         ksls->code = GNUNET_strdup (code);
    143         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    144                     "Read code `%s'\n",
    145                     code);
    146       }
    147       break;
    148     case ANASTASIS_CS_TAN_SENT:
    149       ksls->instructions = GNUNET_strdup (
    150         tcd->details.success.details.tan_address_hint);
    151       break;
    152     case ANASTASIS_CS_TAN_ALREADY_SENT:
    153       break;
    154     case ANASTASIS_CS_WIRE_FUNDS:
    155       /* FIXME: not implemented */
    156       GNUNET_break (0);
    157       return;
    158     }
    159     break;
    160   case MHD_HTTP_PAYMENT_REQUIRED:
    161     ksls->pay_uri = GNUNET_strdup (
    162       tcd->details.payment_required.payment_request);
    163     ksls->payment_secret_response = tcd->details.payment_required.ps;
    164     {
    165       struct TALER_MERCHANT_PayUriData pd;
    166 
    167       if (GNUNET_OK !=
    168           TALER_MERCHANT_parse_pay_uri (ksls->pay_uri,
    169                                         &pd))
    170       {
    171         GNUNET_break (0);
    172         TALER_TESTING_interpreter_fail (ksls->is);
    173         return;
    174       }
    175       ksls->order_id = GNUNET_strdup (pd.order_id);
    176       TALER_MERCHANT_parse_pay_uri_free (&pd);
    177     }
    178 
    179     break;
    180   default:
    181     break;
    182   }
    183   TALER_TESTING_interpreter_next (ksls->is);
    184 }
    185 
    186 
    187 static void
    188 truth_challenge_run (void *cls,
    189                      const struct TALER_TESTING_Command *cmd,
    190                      struct TALER_TESTING_Interpreter *is)
    191 {
    192   struct TruthChallengeState *ksls = cls;
    193   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key;
    194   const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid;
    195   const struct ANASTASIS_PaymentSecretP *payment_secret;
    196 
    197   ksls->is = is;
    198   if (NULL == ksls->upload_reference)
    199   {
    200     GNUNET_break (0);
    201     TALER_TESTING_interpreter_fail (ksls->is);
    202     return;
    203   }
    204   {
    205     const struct TALER_TESTING_Command *upload_cmd;
    206 
    207     upload_cmd = TALER_TESTING_interpreter_lookup_command (
    208       is,
    209       ksls->upload_reference);
    210     if (NULL == upload_cmd)
    211     {
    212       GNUNET_break (0);
    213       TALER_TESTING_interpreter_fail (ksls->is);
    214       return;
    215     }
    216     if (GNUNET_OK !=
    217         ANASTASIS_TESTING_get_trait_truth_uuid (upload_cmd,
    218                                                 &truth_uuid))
    219     {
    220       GNUNET_break (0);
    221       TALER_TESTING_interpreter_fail (ksls->is);
    222       return;
    223     }
    224     if (NULL == truth_uuid)
    225     {
    226       GNUNET_break (0);
    227       TALER_TESTING_interpreter_fail (ksls->is);
    228       return;
    229     }
    230     if (GNUNET_OK !=
    231         ANASTASIS_TESTING_get_trait_truth_key (upload_cmd,
    232                                                &truth_key))
    233     {
    234       GNUNET_break (0);
    235       TALER_TESTING_interpreter_fail (ksls->is);
    236       return;
    237     }
    238     if (NULL == truth_key)
    239     {
    240       GNUNET_break (0);
    241       TALER_TESTING_interpreter_fail (ksls->is);
    242       return;
    243     }
    244   }
    245 
    246   if (NULL != ksls->payment_reference)
    247   {
    248     const struct TALER_TESTING_Command *payment_cmd;
    249 
    250     payment_cmd = TALER_TESTING_interpreter_lookup_command (
    251       is,
    252       ksls->payment_reference);
    253     if (GNUNET_OK !=
    254         ANASTASIS_TESTING_get_trait_payment_secret (payment_cmd,
    255                                                     &payment_secret))
    256     {
    257       GNUNET_break (0);
    258       TALER_TESTING_interpreter_fail (ksls->is);
    259       return;
    260     }
    261   }
    262   else
    263   {
    264     payment_secret = NULL;
    265   }
    266 
    267   ksls->tco = ANASTASIS_truth_challenge (
    268     TALER_TESTING_interpreter_get_context (is),
    269     ksls->anastasis_url,
    270     truth_uuid,
    271     truth_key,
    272     payment_secret,
    273     &truth_challenge_cb,
    274     ksls);
    275   if (NULL == ksls->tco)
    276   {
    277     GNUNET_break (0);
    278     TALER_TESTING_interpreter_fail (ksls->is);
    279     return;
    280   }
    281 }
    282 
    283 
    284 static void
    285 truth_challenge_cleanup (void *cls,
    286                          const struct TALER_TESTING_Command *cmd)
    287 {
    288   struct TruthChallengeState *ksls = cls;
    289 
    290   if (NULL != ksls->tco)
    291   {
    292     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    293                 "Command '%s' did not complete (keyshare lookup)\n",
    294                 cmd->label);
    295     ANASTASIS_truth_challenge_cancel (ksls->tco);
    296     ksls->tco = NULL;
    297   }
    298   GNUNET_free (ksls->pay_uri);
    299   GNUNET_free (ksls->order_id);
    300   GNUNET_free (ksls->code);
    301   GNUNET_free (ksls->instructions);
    302   GNUNET_free (ksls);
    303 }
    304 
    305 
    306 /**
    307  * Offer internal data to other commands.
    308  *
    309  * @param cls closure
    310  * @param[out] ret result (could be anything)
    311  * @param[out] trait name of the trait
    312  * @param index index number of the object to extract.
    313  * @return #GNUNET_OK on success
    314  */
    315 static enum GNUNET_GenericReturnValue
    316 truth_challenge_traits (void *cls,
    317                         const void **ret,
    318                         const char *trait,
    319                         unsigned int index)
    320 {
    321   struct TruthChallengeState *ksls = cls;
    322   struct TALER_TESTING_Trait traits[] = {
    323     ANASTASIS_TESTING_make_trait_payment_secret (
    324       &ksls->payment_secret_response),
    325     TALER_TESTING_make_trait_taler_uri (ksls->pay_uri),
    326     TALER_TESTING_make_trait_order_id (ksls->order_id),
    327     ANASTASIS_TESTING_make_trait_code (ksls->code),
    328     TALER_TESTING_trait_end ()
    329   };
    330 
    331   return TALER_TESTING_get_trait (traits,
    332                                   ret,
    333                                   trait,
    334                                   index);
    335 }
    336 
    337 
    338 struct TALER_TESTING_Command
    339 ANASTASIS_TESTING_cmd_truth_challenge (
    340   const char *label,
    341   const char *anastasis_url,
    342   const char *payment_ref,
    343   const char *upload_ref,
    344   unsigned int http_status)
    345 {
    346   struct TruthChallengeState *ksls;
    347 
    348   GNUNET_assert (NULL != upload_ref);
    349   ksls = GNUNET_new (struct TruthChallengeState);
    350   ksls->expected_http_status = http_status;
    351   ksls->anastasis_url = anastasis_url;
    352   ksls->upload_reference = upload_ref;
    353   ksls->payment_reference = payment_ref;
    354   {
    355     struct TALER_TESTING_Command cmd = {
    356       .cls = ksls,
    357       .label = label,
    358       .run = &truth_challenge_run,
    359       .cleanup = &truth_challenge_cleanup,
    360       .traits = &truth_challenge_traits
    361     };
    362 
    363     return cmd;
    364   }
    365 }
    366 
    367 
    368 /* end of testing_api_cmd_truth_challenge.c */