LCOV - code coverage report
Current view: top level - backend - taler-merchant-httpd_post-management-instances-INSTANCE-auth.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.3 % 184 122
Test Date: 2026-09-04 23:42:01 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :   This file is part of GNU Taler
       3              :   (C) 2021 Taler Systems SA
       4              : 
       5              :   GNU Taler is free software; you can redistribute it and/or modify
       6              :   it under the terms of the GNU Affero General Public License as
       7              :   published by the Free Software Foundation; either version 3,
       8              :   or (at your option) any later version.
       9              : 
      10              :   GNU Taler is distributed in the hope that it will be useful, but
      11              :   WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13              :   GNU General Public License for more details.
      14              : 
      15              :   You should have received a copy of the GNU General Public
      16              :   License along with TALER; see the file COPYING.  If not,
      17              :   see <http://www.gnu.org/licenses/>
      18              : */
      19              : 
      20              : /**
      21              :  * @file src/backend/taler-merchant-httpd_post-management-instances-INSTANCE-auth.c
      22              :  * @brief implementing POST /instances/$ID/auth request handling
      23              :  * @author Christian Grothoff
      24              :  * @author Florian Dold
      25              :  */
      26              : #include "platform.h"
      27              : #include "taler-merchant-httpd_post-management-instances-INSTANCE-auth.h"
      28              : #include "taler-merchant-httpd_auth.h"
      29              : #include "taler-merchant-httpd_helper.h"
      30              : #include "taler-merchant-httpd_mfa.h"
      31              : #include <taler/taler_json_lib.h>
      32              : #include "merchant-database/get_instance_auth.h"
      33              : #include "merchant-database/insert_login_token.h"
      34              : #include "merchant-database/update_instance_auth.h"
      35              : #include "merchant-database/start.h"
      36              : 
      37              : 
      38              : /**
      39              :  * How often do we retry the simple INSERT database transaction?
      40              :  */
      41              : #define MAX_RETRIES 3
      42              : 
      43              : 
      44              : /**
      45              :  * Return a login token created as part of a password reset.
      46              :  *
      47              :  * @param connection connection to respond on
      48              :  * @param token binary value of the token
      49              :  * @param expiration_time when the token expires
      50              :  * @return MHD result code
      51              :  */
      52              : static enum MHD_Result
      53            1 : reply_with_login_token (
      54              :   struct MHD_Connection *connection,
      55              :   const struct TALER_MERCHANTDB_LoginTokenP *token,
      56              :   struct GNUNET_TIME_Timestamp expiration_time)
      57              : {
      58              :   char *token_data;
      59              :   char *access_token;
      60              :   enum MHD_Result ret;
      61              : 
      62            1 :   token_data = GNUNET_STRINGS_data_to_string_alloc (token,
      63              :                                                     sizeof (*token));
      64            1 :   GNUNET_asprintf (&access_token,
      65              :                    RFC_8959_PREFIX "%s",
      66              :                    token_data);
      67            1 :   GNUNET_free (token_data);
      68            1 :   ret = TALER_MHD_REPLY_JSON_PACK (
      69              :     connection,
      70              :     MHD_HTTP_OK,
      71              :     GNUNET_JSON_pack_string ("access_token",
      72              :                              access_token),
      73              :     GNUNET_JSON_pack_string ("token",
      74              :                              access_token),
      75              :     GNUNET_JSON_pack_string ("scope",
      76              :                              "spa"),
      77              :     GNUNET_JSON_pack_bool ("refreshable",
      78              :                            true),
      79              :     GNUNET_JSON_pack_timestamp ("expiration",
      80              :                                 expiration_time));
      81            1 :   GNUNET_free (access_token);
      82            1 :   return ret;
      83              : }
      84              : 
      85              : 
      86              : /**
      87              :  * Change the authentication settings of an instance.
      88              :  *
      89              :  * @param mi instance to modify settings of
      90              :  * @param connection the MHD connection to handle
      91              :  * @param[in,out] hc context with further information about the request
      92              :  * @param auth_override The authentication settings for this instance
      93              :  *   do not apply due to administrative action. Do not check
      94              :  *   against the DB value when updating the auth token.
      95              :  * @param require_old_password require the current password when the
      96              :  *   instance currently uses password authentication
      97              :  * @param tcs set of multi-factor authorizations required
      98              :  * @param mfa_combi_and require all MFA channels in @a tcs instead of any one
      99              :  * @param login_token_duration how long a login token returned after the
     100              :  *   update should remain valid; zero means do not create a token
     101              :  * @return MHD result code
     102              :  */
     103              : static enum MHD_Result
     104           19 : post_instances_ID_auth (struct TMH_MerchantInstance *mi,
     105              :                         struct MHD_Connection *connection,
     106              :                         struct TMH_HandlerContext *hc,
     107              :                         bool auth_override,
     108              :                         bool require_old_password,
     109              :                         enum TEH_TanChannelSet tcs,
     110              :                         bool mfa_combi_and,
     111              :                         struct GNUNET_TIME_Relative login_token_duration)
     112              : {
     113              :   struct TALER_MERCHANTDB_InstanceAuthSettings ias;
     114              :   struct TALER_MERCHANTDB_LoginTokenP login_token;
     115              :   struct GNUNET_TIME_Timestamp token_creation_time;
     116              :   struct GNUNET_TIME_Timestamp token_expiration_time;
     117           19 :   const char *auth_pw = NULL;
     118           19 :   const char *old_password = NULL;
     119           19 :   json_t *jauth = hc->request_body;
     120           19 :   bool issue_login_token
     121           19 :     = ! GNUNET_TIME_relative_is_zero (login_token_duration);
     122              : 
     123           19 :   if (issue_login_token)
     124              :   {
     125            3 :     GNUNET_CRYPTO_random_block (&login_token,
     126              :                                 sizeof (login_token));
     127            3 :     token_creation_time = GNUNET_TIME_timestamp_get ();
     128              :     token_expiration_time
     129            3 :       = GNUNET_TIME_relative_to_timestamp (login_token_duration);
     130              :   }
     131              : 
     132           19 :   if (require_old_password)
     133              :   {
     134           10 :     json_t *jold_password = json_object_get (jauth,
     135              :                                              "old_password");
     136              : 
     137           10 :     if (NULL != jold_password)
     138              :     {
     139            9 :       old_password = json_string_value (jold_password);
     140            9 :       if (NULL == old_password)
     141              :       {
     142            0 :         GNUNET_break_op (0);
     143            0 :         return TALER_MHD_reply_with_error (
     144              :           connection,
     145              :           MHD_HTTP_BAD_REQUEST,
     146              :           TALER_EC_MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH,
     147              :           "old_password must be a string");
     148              :       }
     149              :     }
     150              :   }
     151              : 
     152              :   {
     153              :     enum GNUNET_GenericReturnValue ret;
     154              : 
     155           19 :     ret = TMH_check_auth_config (connection,
     156              :                                  jauth,
     157              :                                  &auth_pw);
     158           19 :     if (GNUNET_OK != ret)
     159            0 :       return (GNUNET_NO == ret) ? MHD_YES : MHD_NO;
     160              :   }
     161              : 
     162              :   {
     163           19 :     enum TEH_TanChannelSet available_tcs = TMH_TCS_NONE;
     164           46 :     bool have_sms = (NULL != mi->settings.phone) &&
     165           27 :                     (NULL != TMH_helper_sms) &&
     166            8 :                     mi->settings.phone_validated;
     167           46 :     bool have_email = (NULL != mi->settings.email) &&
     168           27 :                       (NULL != TMH_helper_email) &&
     169            8 :                       mi->settings.email_validated;
     170              : 
     171           19 :     if (have_sms &&
     172            8 :         (0 != (tcs & TMH_TCS_SMS)))
     173            8 :       available_tcs |= TMH_TCS_SMS;
     174           19 :     if (have_email &&
     175            8 :         (0 != (tcs & TMH_TCS_EMAIL)))
     176            8 :       available_tcs |= TMH_TCS_EMAIL;
     177              : 
     178           19 :     if (mfa_combi_and &&
     179            6 :         (0 != (tcs & TMH_TCS_SMS)) &&
     180            6 :         (! have_sms))
     181              :     {
     182            0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     183              :                   "Cannot change authentication: SMS factor not available\n");
     184            0 :       return TALER_MHD_reply_with_error (
     185              :         connection,
     186              :         MHD_HTTP_FORBIDDEN,
     187              :         TALER_EC_MERCHANT_GENERIC_MFA_MISSING,
     188              :         "phone_number");
     189              :     }
     190           19 :     if (mfa_combi_and &&
     191            6 :         (0 != (tcs & TMH_TCS_EMAIL)) &&
     192            6 :         (! have_email))
     193              :     {
     194            0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     195              :                   "Cannot change authentication: E-mail factor not available\n");
     196            0 :       return TALER_MHD_reply_with_error (
     197              :         connection,
     198              :         MHD_HTTP_FORBIDDEN,
     199              :         TALER_EC_MERCHANT_GENERIC_MFA_MISSING,
     200              :         "email");
     201              :     }
     202           19 :     if ( (TMH_TCS_NONE != tcs) &&
     203              :          (TMH_TCS_NONE == available_tcs) )
     204              :     {
     205              :       const char *missing_factor;
     206              : 
     207            0 :       switch (tcs)
     208              :       {
     209            0 :       case TMH_TCS_SMS:
     210            0 :         missing_factor = "phone_number";
     211            0 :         break;
     212            0 :       case TMH_TCS_EMAIL:
     213            0 :         missing_factor = "email";
     214            0 :         break;
     215            0 :       case TMH_TCS_EMAIL_AND_SMS:
     216            0 :         missing_factor = "phone_number or email";
     217            0 :         break;
     218            0 :       case TMH_TCS_NONE:
     219            0 :         GNUNET_assert (0);
     220              :         missing_factor = NULL;
     221              :         break;
     222              :       }
     223            0 :       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     224              :                   "Cannot change authentication: no MFA factor available\n");
     225            0 :       return TALER_MHD_reply_with_error (
     226              :         connection,
     227              :         MHD_HTTP_FORBIDDEN,
     228              :         TALER_EC_MERCHANT_GENERIC_MFA_MISSING,
     229              :         missing_factor);
     230              :     }
     231           19 :     tcs = available_tcs;
     232              :   }
     233           19 :   if (! auth_override)
     234              :   {
     235           16 :     enum GNUNET_GenericReturnValue ret = GNUNET_SYSERR; // fix -Wmaybe-uninitialized
     236              : 
     237           16 :     switch (tcs)
     238              :     {
     239            8 :     case TMH_TCS_NONE:
     240            8 :       ret = GNUNET_OK;
     241            8 :       break;
     242            0 :     case TMH_TCS_SMS:
     243            0 :       ret = TMH_mfa_challenges_do (hc,
     244            0 :                                    mi->settings.id,
     245              :                                    TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION,
     246              :                                    mfa_combi_and,
     247              :                                    TALER_MERCHANT_MFA_CHANNEL_SMS,
     248              :                                    mi->settings.phone,
     249              :                                    TALER_MERCHANT_MFA_CHANNEL_NONE);
     250            0 :       break;
     251            0 :     case TMH_TCS_EMAIL:
     252            0 :       ret = TMH_mfa_challenges_do (hc,
     253            0 :                                    mi->settings.id,
     254              :                                    TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION,
     255              :                                    mfa_combi_and,
     256              :                                    TALER_MERCHANT_MFA_CHANNEL_EMAIL,
     257              :                                    mi->settings.email,
     258              :                                    TALER_MERCHANT_MFA_CHANNEL_NONE);
     259            0 :       break;
     260            8 :     case TMH_TCS_EMAIL_AND_SMS:
     261            8 :       ret = TMH_mfa_challenges_do (hc,
     262            8 :                                    mi->settings.id,
     263              :                                    TALER_MERCHANT_MFA_CO_AUTH_CONFIGURATION,
     264              :                                    mfa_combi_and,
     265              :                                    TALER_MERCHANT_MFA_CHANNEL_EMAIL,
     266              :                                    mi->settings.email,
     267              :                                    TALER_MERCHANT_MFA_CHANNEL_SMS,
     268              :                                    mi->settings.phone,
     269              :                                    TALER_MERCHANT_MFA_CHANNEL_NONE);
     270            8 :       break;
     271              :     }
     272           16 :     if (GNUNET_OK != ret)
     273              :     {
     274              :       return (GNUNET_NO == ret)
     275              :         ? MHD_YES
     276            5 :         : MHD_NO;
     277              :     }
     278              :   }
     279              : 
     280           14 :   if (NULL == auth_pw)
     281              :   {
     282            2 :     memset (&ias.auth_salt,
     283              :             0,
     284              :             sizeof (ias.auth_salt));
     285            2 :     memset (&ias.auth_hash,
     286              :             0,
     287              :             sizeof (ias.auth_hash));
     288              :   }
     289              :   else
     290              :   {
     291           12 :     TMH_compute_auth (auth_pw,
     292              :                       &ias.auth_salt,
     293              :                       &ias.auth_hash);
     294              :   }
     295              : 
     296              :   /* Store the new auth information in the database */
     297              :   {
     298              :     enum GNUNET_DB_QueryStatus qs;
     299              : 
     300           14 :     for (unsigned int i = 0; i<MAX_RETRIES; i++)
     301              :     {
     302           14 :       if (GNUNET_OK !=
     303           14 :           TALER_MERCHANTDB_start (TMH_db,
     304              :                                   "post /instances/$ID/auth"))
     305              :       {
     306            0 :         return TALER_MHD_reply_with_error (connection,
     307              :                                            MHD_HTTP_INTERNAL_SERVER_ERROR,
     308              :                                            TALER_EC_GENERIC_DB_START_FAILED,
     309              :                                            NULL);
     310              :       }
     311              : 
     312              :       /* Make the authentication update a serializable operation.
     313              :          We first check that the authentication information
     314              :          that the caller's request authenticated with
     315              :          is still up to date.
     316              :          Otherwise, we've detected a conflicting update
     317              :          to the authentication. */
     318              :       {
     319              :         struct TALER_MERCHANTDB_InstanceAuthSettings db_ias;
     320              :         enum TALER_ErrorCode ec;
     321              : 
     322           14 :         qs = TALER_MERCHANTDB_get_instance_auth (TMH_db,
     323           14 :                                                  mi->settings.id,
     324              :                                                  &db_ias);
     325              : 
     326           14 :         switch (qs)
     327              :         {
     328            0 :         case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     329              :           /* Instance got purged. */
     330            0 :           TALER_MERCHANTDB_rollback (TMH_db);
     331            2 :           return TALER_MHD_reply_with_error (connection,
     332              :                                              MHD_HTTP_NOT_FOUND,
     333              :                                              TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN,
     334              :                                              NULL);
     335            0 :         case GNUNET_DB_STATUS_SOFT_ERROR:
     336            0 :           TALER_MERCHANTDB_rollback (TMH_db);
     337            0 :           goto retry;
     338            0 :         case GNUNET_DB_STATUS_HARD_ERROR:
     339            0 :           TALER_MERCHANTDB_rollback (TMH_db);
     340            0 :           return TALER_MHD_reply_with_error (connection,
     341              :                                              MHD_HTTP_INTERNAL_SERVER_ERROR,
     342              :                                              TALER_EC_GENERIC_DB_FETCH_FAILED,
     343              :                                              NULL);
     344           14 :         case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     345              :           /* Success! */
     346           14 :           break;
     347              :         }
     348              : 
     349           14 :         if (! auth_override)
     350              :         {
     351              :           // FIXME are we sure what the scope here is?
     352           11 :           ec = TMH_check_token (hc->auth_token,
     353           11 :                                 mi->settings.id,
     354              :                                 &hc->auth_scope);
     355           11 :           if (TALER_EC_NONE != ec)
     356              :           {
     357            0 :             TALER_MERCHANTDB_rollback (TMH_db);
     358            0 :             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     359              :                         "Refusing auth change: `%s'\n",
     360              :                         TALER_ErrorCode_get_hint (ec));
     361            0 :             return TALER_MHD_reply_with_error (connection,
     362              :                                                MHD_HTTP_UNAUTHORIZED,
     363              :                                                TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED,
     364              :                                                NULL);
     365              :           }
     366              :         }
     367           23 :         if (require_old_password &&
     368              :             (GNUNET_OK !=
     369            9 :              TMH_check_auth (old_password,
     370              :                              &db_ias.auth_salt,
     371              :                              &db_ias.auth_hash)))
     372              :         {
     373            2 :           TALER_MERCHANTDB_rollback (TMH_db);
     374            2 :           return TALER_MHD_reply_with_error (
     375              :             connection,
     376              :             MHD_HTTP_UNAUTHORIZED,
     377              :             TALER_EC_MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_OLD_PASSWORD,
     378              :             NULL);
     379              :         }
     380              :       }
     381              : 
     382           12 :       qs = TALER_MERCHANTDB_update_instance_auth (TMH_db,
     383           12 :                                                   mi->settings.id,
     384              :                                                   &ias);
     385           12 :       if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
     386              :       {
     387            0 :         GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
     388            0 :         TALER_MERCHANTDB_rollback (TMH_db);
     389            0 :         if (GNUNET_DB_STATUS_HARD_ERROR == qs)
     390              :         {
     391            0 :           return TALER_MHD_reply_with_error (connection,
     392              :                                              MHD_HTTP_INTERNAL_SERVER_ERROR,
     393              :                                              TALER_EC_GENERIC_DB_FETCH_FAILED,
     394              :                                              NULL);
     395              :         }
     396            0 :         goto retry;
     397              :       }
     398           12 :       if (issue_login_token)
     399              :       {
     400            1 :         qs = TALER_MERCHANTDB_insert_login_token (
     401              :           TMH_db,
     402            1 :           mi->settings.id,
     403              :           &login_token,
     404              :           token_creation_time,
     405              :           token_expiration_time,
     406              :           TMH_AS_REFRESHABLE | TMH_AS_SPA,
     407              :           "login token from password reset");
     408            1 :         switch (qs)
     409              :         {
     410            0 :         case GNUNET_DB_STATUS_SOFT_ERROR:
     411            0 :           TALER_MERCHANTDB_rollback (TMH_db);
     412            0 :           goto retry;
     413            0 :         case GNUNET_DB_STATUS_HARD_ERROR:
     414              :         case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     415            0 :           GNUNET_break (0);
     416            0 :           TALER_MERCHANTDB_rollback (TMH_db);
     417            0 :           return TALER_MHD_reply_with_error (
     418              :             connection,
     419              :             MHD_HTTP_INTERNAL_SERVER_ERROR,
     420              :             TALER_EC_GENERIC_DB_STORE_FAILED,
     421              :             "insert_login_token");
     422            1 :         case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     423            1 :           break;
     424              :         }
     425              :       }
     426           12 :       qs = TALER_MERCHANTDB_commit (TMH_db);
     427           12 :       if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     428           12 :         qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
     429            0 : retry:
     430           12 :       if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
     431           12 :         break; /* success! -- or hard failure */
     432              :     } /* for .. MAX_RETRIES */
     433           12 :     if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
     434              :     {
     435            0 :       return TALER_MHD_reply_with_error (connection,
     436              :                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
     437              :                                          TALER_EC_GENERIC_DB_COMMIT_FAILED,
     438              :                                          NULL);
     439              :     }
     440              :     /* Finally, also update our running process */
     441           12 :     mi->auth = ias;
     442              :   }
     443           12 :   TMH_reload_instances (mi->settings.id);
     444           12 :   if (issue_login_token)
     445            1 :     return reply_with_login_token (connection,
     446              :                                    &login_token,
     447              :                                    token_expiration_time);
     448           11 :   return TALER_MHD_reply_static (connection,
     449              :                                  MHD_HTTP_NO_CONTENT,
     450              :                                  NULL,
     451              :                                  NULL,
     452              :                                  0);
     453              : }
     454              : 
     455              : 
     456              : enum MHD_Result
     457           10 : TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh,
     458              :                                     struct MHD_Connection *connection,
     459              :                                     struct TMH_HandlerContext *hc)
     460              : {
     461           10 :   struct TMH_MerchantInstance *mi = hc->instance;
     462              : 
     463           10 :   return post_instances_ID_auth (mi,
     464              :                                  connection,
     465              :                                  hc,
     466              :                                  false,
     467              :                                  true,
     468           10 :                                  (GNUNET_YES == TMH_password_change_mfa)
     469              :                                  ? TEH_mandatory_tan_channels
     470              :                                  : TMH_TCS_NONE,
     471              :                                  false,
     472           10 :                                  GNUNET_TIME_UNIT_ZERO);
     473              : }
     474              : 
     475              : 
     476              : enum MHD_Result
     477            6 : TMH_public_post_instances_ID_auth (const struct TMH_RequestHandler *rh,
     478              :                                    struct MHD_Connection *connection,
     479              :                                    struct TMH_HandlerContext *hc)
     480              : {
     481            6 :   struct TMH_MerchantInstance *mi = hc->instance;
     482            6 :   struct GNUNET_TIME_Relative token_duration = GNUNET_TIME_UNIT_ZERO;
     483              :   struct GNUNET_JSON_Specification spec[] = {
     484            6 :     GNUNET_JSON_spec_mark_optional (
     485              :       GNUNET_JSON_spec_relative_time ("token_duration",
     486              :                                       &token_duration),
     487              :       NULL),
     488            6 :     GNUNET_JSON_spec_end ()
     489              :   };
     490              : 
     491              :   {
     492              :     enum GNUNET_GenericReturnValue res;
     493              : 
     494            6 :     res = TALER_MHD_parse_json_data (connection,
     495            6 :                                      hc->request_body,
     496              :                                      spec);
     497            6 :     if (GNUNET_OK != res)
     498            0 :       return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
     499              :   }
     500            6 :   GNUNET_JSON_parse_free (spec);
     501              : 
     502            6 :   if (0 == strcmp ("admin",
     503            6 :                    mi->settings.id))
     504              :   {
     505            0 :     GNUNET_break_op (0);
     506            0 :     return TALER_MHD_reply_with_error (
     507              :       connection,
     508              :       MHD_HTTP_FORBIDDEN,
     509              :       TALER_EC_MERCHANT_GENERIC_MFA_MISSING,
     510              :       "not allowed for 'admin' account");
     511              :   }
     512            6 :   if (TMH_TCS_NONE == TEH_mandatory_tan_channels)
     513              :   {
     514              :     /* This endpoint changes the instance password *without* requiring
     515              :        the current password; the only thing standing between an
     516              :        anonymous client and a full account takeover is the MFA
     517              :        challenge.  If no TAN channel is mandatory, we have no second
     518              :        factor to require and thus must refuse the request. */
     519            0 :     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
     520              :                 "Refusing password reset: no mandatory TAN channel configured\n");
     521            0 :     return TALER_MHD_reply_with_error (
     522              :       connection,
     523              :       MHD_HTTP_FORBIDDEN,
     524              :       TALER_EC_MERCHANT_GENERIC_MFA_MISSING,
     525              :       "MANDATORY_TAN_CHANNELS");
     526              :   }
     527            6 :   return post_instances_ID_auth (mi,
     528              :                                  connection,
     529              :                                  hc,
     530              :                                  false,
     531              :                                  false,
     532              :                                  TEH_mandatory_tan_channels,
     533              :                                  true,
     534              :                                  token_duration);
     535              : }
     536              : 
     537              : 
     538              : enum MHD_Result
     539            3 : TMH_private_post_instances_default_ID_auth (
     540              :   const struct TMH_RequestHandler *rh,
     541              :   struct MHD_Connection *connection,
     542              :   struct TMH_HandlerContext *hc)
     543              : {
     544              :   struct TMH_MerchantInstance *mi;
     545              :   enum MHD_Result ret;
     546              : 
     547            3 :   mi = TMH_lookup_instance (hc->infix);
     548            3 :   if (NULL == mi)
     549              :   {
     550            0 :     return TALER_MHD_reply_with_error (
     551              :       connection,
     552              :       MHD_HTTP_NOT_FOUND,
     553              :       TALER_EC_MERCHANT_GENERIC_INSTANCE_UNKNOWN,
     554            0 :       hc->infix);
     555              :   }
     556            3 :   ret = post_instances_ID_auth (mi,
     557              :                                 connection,
     558              :                                 hc,
     559              :                                 true,
     560              :                                 false,
     561              :                                 TMH_TCS_NONE,
     562              :                                 false,
     563            3 :                                 GNUNET_TIME_UNIT_ZERO);
     564            3 :   return ret;
     565              : }
     566              : 
     567              : 
     568              : /* end of taler-merchant-httpd_post-management-instances-INSTANCE-auth.c */
        

Generated by: LCOV version 2.0-1