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: 41 48 85.4 %
Date: 2025-08-28 06:06:54 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          15 : TMH_private_post_instances_ID_token (const struct TMH_RequestHandler *rh,
      38             :                                      struct MHD_Connection *connection,
      39             :                                      struct TMH_HandlerContext *hc)
      40             : {
      41          15 :   struct TMH_MerchantInstance *mi = hc->instance;
      42          15 :   json_t *jtoken = hc->request_body;
      43             :   const char *scope;
      44             :   const char *description;
      45          15 :   uint32_t iscope = TMH_AS_NONE;
      46          15 :   bool refreshable = false;
      47             :   struct TALER_MERCHANTDB_LoginTokenP btoken;
      48             :   struct GNUNET_TIME_Relative duration
      49          15 :     = DEFAULT_DURATION;
      50             :   struct GNUNET_TIME_Timestamp expiration_time;
      51             :   struct GNUNET_JSON_Specification spec[] = {
      52          15 :     GNUNET_JSON_spec_string ("scope",
      53             :                              &scope),
      54          15 :     GNUNET_JSON_spec_mark_optional (
      55             :       GNUNET_JSON_spec_relative_time ("duration",
      56             :                                       &duration),
      57             :       NULL),
      58          15 :     GNUNET_JSON_spec_mark_optional (
      59             :       GNUNET_JSON_spec_bool ("refreshable",
      60             :                              &refreshable),
      61             :       NULL),
      62          15 :     GNUNET_JSON_spec_mark_optional (
      63             :       GNUNET_JSON_spec_string ("description",
      64             :                                &description),
      65             :       NULL),
      66          15 :     GNUNET_JSON_spec_end ()
      67             :   };
      68             :   enum GNUNET_DB_QueryStatus qs;
      69             : 
      70             :   {
      71             :     enum GNUNET_GenericReturnValue res;
      72             : 
      73          15 :     res = TALER_MHD_parse_json_data (connection,
      74             :                                      jtoken,
      75             :                                      spec);
      76          15 :     if (GNUNET_OK != res)
      77           0 :       return (GNUNET_NO == res) ? MHD_YES : MHD_NO;
      78             :   }
      79          15 :   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
      80             :                               &btoken,
      81             :                               sizeof (btoken));
      82          15 :   expiration_time = GNUNET_TIME_relative_to_timestamp (duration);
      83             :   {
      84             :     char *tmp_scope;
      85             :     char *scope_prefix;
      86             :     char *scope_suffix;
      87          15 :     tmp_scope = GNUNET_strdup (scope);
      88          15 :     scope_prefix = strtok (tmp_scope, ":");
      89          15 :     scope_suffix = strtok (NULL, ":");
      90             : 
      91             :     /* We allow <SCOPE>:REFRESHABLE syntax */
      92          15 :     if ((NULL != scope_suffix) &&
      93           2 :         (0 == strcasecmp (scope_suffix, "refreshable")))
      94           2 :       refreshable = true;
      95          15 :     iscope = TMH_get_scope_by_name (scope_prefix);
      96          15 :     if (TMH_AS_NONE == iscope)
      97             :     {
      98           0 :       GNUNET_break_op (0);
      99           0 :       GNUNET_free (tmp_scope);
     100           0 :       return TALER_MHD_reply_with_ec (connection,
     101             :                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
     102             :                                       "scope");
     103             :     }
     104             :   }
     105          15 :   if (refreshable)
     106           9 :     iscope |= TMH_AS_REFRESHABLE;
     107          15 :   if (! TMH_scope_is_subset (hc->auth_scope, iscope))
     108             :   {
     109             :     /* more permissions requested for the new token, not allowed */
     110           1 :     GNUNET_break_op (0);
     111           1 :     return TALER_MHD_reply_with_ec (connection,
     112             :                                     TALER_EC_GENERIC_TOKEN_PERMISSION_INSUFFICIENT,
     113             :                                     NULL);
     114             :   }
     115          14 :   if (NULL == description)
     116             :   {
     117          13 :     description = "";
     118             :   }
     119          14 :   qs = TMH_db->insert_login_token (TMH_db->cls,
     120          14 :                                    mi->settings.id,
     121             :                                    &btoken,
     122             :                                    GNUNET_TIME_timestamp_get (),
     123             :                                    expiration_time,
     124             :                                    iscope,
     125             :                                    description);
     126          14 :   switch (qs)
     127             :   {
     128           0 :   case GNUNET_DB_STATUS_HARD_ERROR:
     129             :   case GNUNET_DB_STATUS_SOFT_ERROR:
     130             :   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
     131           0 :     GNUNET_break (0);
     132           0 :     return TALER_MHD_reply_with_ec (connection,
     133             :                                     TALER_EC_GENERIC_DB_STORE_FAILED,
     134             :                                     "insert_login_token");
     135          14 :   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
     136          14 :     break;
     137             :   }
     138             : 
     139             :   {
     140             :     char *tok;
     141             :     MHD_RESULT ret;
     142             :     char *val;
     143             : 
     144          14 :     val = GNUNET_STRINGS_data_to_string_alloc (&btoken,
     145             :                                                sizeof (btoken));
     146          14 :     GNUNET_asprintf (&tok,
     147             :                      RFC_8959_PREFIX "%s",
     148             :                      val);
     149          14 :     GNUNET_free (val);
     150          14 :     ret = TALER_MHD_REPLY_JSON_PACK (
     151             :       connection,
     152             :       MHD_HTTP_OK,
     153             :       GNUNET_JSON_pack_string ("access_token",
     154             :                                tok),
     155             :       GNUNET_JSON_pack_string ("token",
     156             :                                tok),
     157             :       GNUNET_JSON_pack_string ("scope",
     158             :                                scope),
     159             :       GNUNET_JSON_pack_bool ("refreshable",
     160             :                              refreshable),
     161             :       GNUNET_JSON_pack_timestamp ("expiration",
     162             :                                   expiration_time));
     163          14 :     GNUNET_free (tok);
     164          14 :     return ret;
     165             :   }
     166             : }
     167             : 
     168             : 
     169             : /* end of taler-merchant-httpd_private-post-instances-ID-token.c */

Generated by: LCOV version 1.16