LCOV - code coverage report
Current view: top level - backend - taler-merchant-httpd_private-post-instances-ID-token.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 36 45 80.0 %
Date: 2025-06-23 16:22:09 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :   This file is part of GNU Taler
       3             :   (C) 2023 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 taler-merchant-httpd_private-post-instances-ID-token.c
      22             :  * @brief implementing POST /instances/$ID/token request handling
      23             :  * @author Christian Grothoff
      24             :  */
      25             : #include "platform.h"
      26             : #include "taler-merchant-httpd_private-post-instances-ID-token.h"
      27             : #include "taler-merchant-httpd_helper.h"
      28             : #include <taler/taler_json_lib.h>
      29             : 
      30             : 
      31             : /**
      32             :  * Default duration for the validity of a login token.
      33             :  */
      34             : #define DEFAULT_DURATION GNUNET_TIME_UNIT_DAYS
      35             : 
      36             : MHD_RESULT
      37          11 : TMH_private_post_instances_ID_token (const struct TMH_RequestHandler *rh,
      38             :                                      struct MHD_Connection *connection,
      39             :                                      struct TMH_HandlerContext *hc)
      40             : {
      41          11 :   struct TMH_MerchantInstance *mi = hc->instance;
      42          11 :   json_t *jtoken = hc->request_body;
      43             :   const char *scope;
      44          11 :   uint32_t iscope = TMH_AS_NONE;
      45          11 :   bool refreshable = false;
      46             :   struct TALER_MERCHANTDB_LoginTokenP btoken;
      47             :   struct GNUNET_TIME_Relative duration
      48          11 :     = DEFAULT_DURATION;
      49             :   struct GNUNET_TIME_Timestamp expiration_time;
      50             :   struct GNUNET_JSON_Specification spec[] = {
      51          11 :     GNUNET_JSON_spec_string ("scope",
      52             :                              &scope),
      53          11 :     GNUNET_JSON_spec_mark_optional (
      54             :       GNUNET_JSON_spec_relative_time ("duration",
      55             :                                       &duration),
      56             :       NULL),
      57          11 :     GNUNET_JSON_spec_mark_optional (
      58             :       GNUNET_JSON_spec_bool ("refreshable",
      59             :                              &refreshable),
      60             :       NULL),
      61          11 :     GNUNET_JSON_spec_end ()
      62             :   };
      63             :   enum GNUNET_DB_QueryStatus qs;
      64             : 
      65             :   {
      66             :     enum GNUNET_GenericReturnValue res;
      67             : 
      68          11 :     res = TALER_MHD_parse_json_data (connection,
      69             :                                      jtoken,
      70             :                                      spec);
      71          11 :     if (GNUNET_OK != res)
      72           0 :       return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
      73             :   }
      74          11 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
      75             :                               &btoken,
      76             :                               sizeof (btoken));
      77          11 :   expiration_time = GNUNET_TIME_relative_to_timestamp (duration);
      78             :   {
      79             :     char *tmp_scope;
      80             :     char *scope_prefix;
      81             :     char *scope_suffix;
      82          11 :     tmp_scope = GNUNET_strdup (scope);
      83          11 :     scope_prefix = strtok (tmp_scope, ":");
      84          11 :     scope_suffix = strtok (NULL, ":");
      85             : 
      86             :     /* We allow <SCOPE>:REFRESHABLE syntax */
      87          11 :     if ((NULL != scope_suffix) &&
      88           0 :         (0 == strcasecmp (scope_suffix, "refreshable")))
      89           0 :       refreshable = true;
      90          11 :     iscope = TMH_get_scope_by_name (scope_prefix);
      91          11 :     if (TMH_AS_NONE == iscope)
      92             :     {
      93           0 :       GNUNET_break_op (0);
      94           0 :       GNUNET_free (tmp_scope);
      95           0 :       return TALER_MHD_reply_with_ec (connection,
      96             :                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
      97             :                                       "scope");
      98             :     }
      99             :   }
     100          11 :   if (refreshable)
     101           7 :     iscope |= TMH_AS_REFRESHABLE;
     102          11 :   if (! TMH_scope_is_subset (hc->auth_scope, iscope))
     103             :   {
     104             :     /* more permissions requested for the new token, not allowed */
     105           1 :     GNUNET_break_op (0);
     106           1 :     return TALER_MHD_reply_with_ec (connection,
     107             :                                     TALER_EC_GENERIC_TOKEN_PERMISSION_INSUFFICIENT,
     108             :                                     NULL);
     109             :   }
     110          10 :   qs = TMH_db->insert_login_token (TMH_db->cls,
     111          10 :                                    mi->settings.id,
     112             :                                    &btoken,
     113             :                                    GNUNET_TIME_timestamp_get (),
     114             :                                    expiration_time,
     115             :                                    iscope);
     116          10 :   switch (qs)
     117             :   {
     118           0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     119             :   case GNUNET_DB_STATUS_SOFT_ERROR:
     120             :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     121           0 :     GNUNET_break (0);
     122           0 :     return TALER_MHD_reply_with_ec (connection,
     123             :                                     TALER_EC_GENERIC_DB_STORE_FAILED,
     124             :                                     "insert_login_token");
     125          10 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     126          10 :     break;
     127             :   }
     128             : 
     129             :   {
     130             :     char *tok;
     131             :     MHD_RESULT ret;
     132             :     char *val;
     133             : 
     134          10 :     val = GNUNET_STRINGS_data_to_string_alloc (&btoken,
     135             :                                                sizeof (btoken));
     136          10 :     GNUNET_asprintf (&tok,
     137             :                      RFC_8959_PREFIX "%s",
     138             :                      val);
     139          10 :     GNUNET_free (val);
     140          10 :     ret = TALER_MHD_REPLY_JSON_PACK (
     141             :       connection,
     142             :       MHD_HTTP_OK,
     143             :       GNUNET_JSON_pack_string ("access_token",
     144             :                                tok),
     145             :       GNUNET_JSON_pack_string ("token",
     146             :                                tok),
     147             :       GNUNET_JSON_pack_string ("scope",
     148             :                                scope),
     149             :       GNUNET_JSON_pack_bool ("refreshable",
     150             :                              refreshable),
     151             :       GNUNET_JSON_pack_timestamp ("expiration",
     152             :                                   expiration_time));
     153          10 :     GNUNET_free (tok);
     154          10 :     return ret;
     155             :   }
     156             : }
     157             : 
     158             : 
     159             : /* end of taler-merchant-httpd_private-post-instances-ID-token.c */

Generated by: LCOV version 1.16