challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

challenger-httpd_info.c (5058B)


      1 /*
      2   This file is part of Challenger
      3   Copyright (C) 2023 Taler Systems SA
      4 
      5   Challenger is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   Challenger 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   Challenger; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file challenger-httpd_info.c
     18  * @brief functions to handle incoming requests for infos
     19  * @author Christian Grothoff
     20  */
     21 #include "platform.h"
     22 #include "challenger-httpd.h"
     23 #include <gnunet/gnunet_util_lib.h>
     24 #include <gnunet/gnunet_db_lib.h>
     25 #include "challenger-httpd_common.h"
     26 #include "challenger-httpd_info.h"
     27 #include "challenger-database/info_get_token.h"
     28 
     29 
     30 /**
     31  * Prefix of a 'Bearer' token in an 'Authorization' HTTP header.
     32  */
     33 #define BEARER_PREFIX "Bearer "
     34 
     35 
     36 /**
     37  * Maximum number of retries for the database interaction.
     38  */
     39 #define MAX_RETRIES 3
     40 
     41 enum MHD_Result
     42 CH_handler_info (struct CH_HandlerContext *hc,
     43                  const char *upload_data,
     44                  size_t *upload_data_size)
     45 {
     46   const char *auth;
     47   const char *token;
     48   struct CHALLENGER_AccessTokenP grant;
     49 
     50   (void) upload_data;
     51   (void) upload_data_size;
     52   auth = MHD_lookup_connection_value (hc->connection,
     53                                       MHD_HEADER_KIND,
     54                                       MHD_HTTP_HEADER_AUTHORIZATION);
     55   if (NULL == auth)
     56   {
     57     GNUNET_break_op (0);
     58     return TALER_MHD_reply_with_error (hc->connection,
     59                                        MHD_HTTP_FORBIDDEN,
     60                                        TALER_EC_GENERIC_PARAMETER_MISSING,
     61                                        MHD_HTTP_HEADER_AUTHORIZATION);
     62   }
     63   if (0 != strncmp (auth,
     64                     BEARER_PREFIX,
     65                     strlen (BEARER_PREFIX)))
     66   {
     67     GNUNET_break_op (0);
     68     return TALER_MHD_reply_with_error (hc->connection,
     69                                        MHD_HTTP_FORBIDDEN,
     70                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     71                                        MHD_HTTP_HEADER_AUTHORIZATION);
     72   }
     73   token = auth + strlen (BEARER_PREFIX);
     74 
     75   if (GNUNET_OK !=
     76       GNUNET_STRINGS_string_to_data (token,
     77                                      strlen (token),
     78                                      &grant,
     79                                      sizeof (grant)))
     80   {
     81     GNUNET_break_op (0);
     82     return TALER_MHD_reply_with_error (hc->connection,
     83                                        MHD_HTTP_FORBIDDEN,
     84                                        TALER_EC_GENERIC_PARAMETER_MALFORMED,
     85                                        MHD_HTTP_HEADER_AUTHORIZATION);
     86   }
     87 
     88   /* Check token is valid */
     89   for (unsigned int r = 0; r<MAX_RETRIES; r++)
     90   {
     91     uint64_t id;
     92     json_t *address;
     93     enum GNUNET_DB_QueryStatus qs;
     94     struct GNUNET_TIME_Timestamp address_expiration;
     95 
     96     qs = CHALLENGERDB_info_get_token (CH_context,
     97                                       &grant,
     98                                       &id,
     99                                       &address,
    100                                       &address_expiration);
    101     switch (qs)
    102     {
    103     case GNUNET_DB_STATUS_HARD_ERROR:
    104       GNUNET_break (0);
    105       return TALER_MHD_reply_with_error (hc->connection,
    106                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
    107                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
    108                                          "info_get_token");
    109     case GNUNET_DB_STATUS_SOFT_ERROR:
    110       if (r < MAX_RETRIES - 1)
    111         continue;
    112       GNUNET_break (0);
    113       return TALER_MHD_reply_with_error (hc->connection,
    114                                          MHD_HTTP_INTERNAL_SERVER_ERROR,
    115                                          TALER_EC_GENERIC_DB_FETCH_FAILED,
    116                                          "info_get_token");
    117     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    118       return TALER_MHD_reply_with_error (hc->connection,
    119                                          MHD_HTTP_NOT_FOUND,
    120                                          TALER_EC_CHALLENGER_GRANT_UNKNOWN,
    121                                          "info_get_token");
    122     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    123       break;
    124     }
    125     return TALER_MHD_REPLY_JSON_PACK (
    126       hc->connection,
    127       MHD_HTTP_OK,
    128       GNUNET_JSON_pack_uint64 ("id",
    129                                id),
    130       GNUNET_JSON_pack_object_steal ("address",
    131                                      address),
    132       GNUNET_JSON_pack_string ("address_type",
    133                                CH_address_type),
    134       GNUNET_JSON_pack_timestamp ("expires",
    135                                   address_expiration));
    136   }
    137   GNUNET_assert (0);
    138   return MHD_NO;
    139 }