diff options
Diffstat (limited to 'src/include/taler_util.h')
-rw-r--r-- | src/include/taler_util.h | 342 |
1 files changed, 331 insertions, 11 deletions
diff --git a/src/include/taler_util.h b/src/include/taler_util.h index afc8ebada..8feb8451c 100644 --- a/src/include/taler_util.h +++ b/src/include/taler_util.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + Copyright (C) 2014-2024 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -16,11 +16,17 @@ /** * @file include/taler_util.h * @brief Interface for common utility functions + * This library is not thread-safe, all APIs must only be used from a single thread. + * This library calls abort() if it runs out of memory. Be aware of these limitations. * @author Sree Harsha Totakura <sreeharsha@totakura.in> + * @author Christian Grothoff */ #ifndef TALER_UTIL_H #define TALER_UTIL_H +#include <gnunet/gnunet_common.h> +#define __TALER_UTIL_LIB_H_INSIDE__ + #include <gnunet/gnunet_util_lib.h> #include <microhttpd.h> #include "taler_amount_lib.h" @@ -30,7 +36,7 @@ * Version of the Taler API, in hex. * Thus 0.8.4-1 = 0x00080401. */ -#define TALER_API_VERSION 0x00080401 +#define TALER_API_VERSION 0x00090401 /** * Stringify operator. @@ -79,6 +85,22 @@ /** + * HTTP header with an AML officer signature to approve the inquiry. + * Used only in GET Requests. + */ +#define TALER_AML_OFFICER_SIGNATURE_HEADER "Taler-AML-Officer-Signature" + +/** + * Header with signature for reserve history requests. + */ +#define TALER_RESERVE_HISTORY_SIGNATURE_HEADER "Taler-Reserve-History-Signature" + +/** + * Header with signature for coin history requests. + */ +#define TALER_COIN_HISTORY_SIGNATURE_HEADER "Taler-Coin-History-Signature" + +/** * Log an error message at log-level 'level' that indicates * a failure of the command 'cmd' with the message given * by gcry_strerror(rc). @@ -191,6 +213,101 @@ TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg, /** + * Details about how to render a currency. + */ +struct TALER_CurrencySpecification +{ + /** + * Currency code of the currency. + */ + char currency[TALER_CURRENCY_LEN]; + + /** + * Human-readable long name of the currency, e.g. + * "Japanese Yen". + */ + char *name; + + /** + * how many digits the user may enter at most after the @e decimal_separator + */ + unsigned int num_fractional_input_digits; + + /** + * how many digits we render in normal scale after the @e decimal_separator + */ + unsigned int num_fractional_normal_digits; + + /** + * how many digits we render in after the @e decimal_separator even if all + * remaining digits are zero. + */ + unsigned int num_fractional_trailing_zero_digits; + + /** + * Mapping of powers of 10 to alternative currency names or symbols. + * Keys are the decimal powers, values the currency symbol to use. + * Map MUST contain an entry for "0" to the default currency symbol. + */ + json_t *map_alt_unit_names; + +}; + + +/** + * Parse information about supported currencies from + * our configuration. + * + * @param cfg configuration to parse + * @param[out] num_currencies set to number of enabled currencies, length of @e cspecs + * @param[out] cspecs set to currency specification array + * @return #GNUNET_OK on success, #GNUNET_NO if zero + * currency specifications were enabled, + * #GNUNET_SYSERR if the configuration was malformed + */ +enum GNUNET_GenericReturnValue +TALER_CONFIG_parse_currencies (const struct GNUNET_CONFIGURATION_Handle *cfg, + unsigned int *num_currencies, + struct TALER_CurrencySpecification **cspecs); + + +/** + * Free @a cspecs array. + * + * @param num_currencies length of @a cspecs array + * @param[in] cspecs array to free + */ +void +TALER_CONFIG_free_currencies ( + unsigned int num_currencies, + struct TALER_CurrencySpecification cspecs[static num_currencies]); + + +/** + * Convert a currency specification to the + * respective JSON object. + * + * @param cspec currency specification + * @return JSON object encoding @a cspec for `/config`. + */ +json_t * +TALER_CONFIG_currency_specs_to_json ( + const struct TALER_CurrencySpecification *cspec); + + +/** + * Check that @a map contains a valid currency scale + * map that maps integers from [-12,24] to currency + * symbols given as strings. + * + * @param map map to check + * @return #GNUNET_OK if @a map is valid + */ +enum GNUNET_GenericReturnValue +TALER_check_currency_scale_map (const json_t *map); + + +/** * Allow user to specify an amount on the command line. * * @param shortName short name of the option @@ -222,6 +339,16 @@ TALER_OS_init (void); /** + * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2). + * + * @param[in,out] inp pointer to string to re-encode + * @return number of bytes in resulting @a inp + */ +size_t +TALER_rfc8785encode (char **inp); + + +/** * URL-encode a string according to rfc3986. * * @param s string to encode @@ -243,6 +370,17 @@ TALER_url_valid_charset (const char *url); /** + * Test if the URL is a valid "http" (or "https") + * URL (includes test for #TALER_url_valid_charset()). + * + * @param url a string to test if it could be a valid URL + * @return true if @a url is well-formed + */ +bool +TALER_is_web_url (const char *url); + + +/** * Check if @a lang matches the @a language_pattern, and if so with * which preference. * See also: https://tools.ietf.org/html/rfc7231#section-5.3.1 @@ -278,8 +416,9 @@ TALER_mhd_is_https (struct MHD_Connection *connection); * that a NULL value does not terminate the list, only a NULL key signals the * end of the list of arguments. * - * @param base_url absolute base URL to use - * @param path path of the url + * @param base_url absolute base URL to use, must either + * end with '/' *or* @a path must be the empty string + * @param path path of the url to append to the @a base_url * @param ... NULL-terminated key-value pairs (char *) for query parameters, * only the value will be url-encoded * @returns the URL, must be freed with #GNUNET_free @@ -362,16 +501,17 @@ TALER_payto_get_method (const char *payto_uri); /** - * Construct a payto://-URI from a Taler @a reserve_pub at - * @a exchange_base_url + * Normalize payto://-URI to make "strcmp()" sufficient + * to check if two payto-URIs refer to the same bank + * account. Removes optional arguments (everything after + * "?") and applies method-specific normalizations to + * the main part of the URI. * - * @param exchange_base_url the URL of the exchange - * @param reserve_pub public key of the reserve - * @return payto:// URI encoding the reserve's address + * @param input a payto://-URI + * @return normalized URI, or NULL if @a input was not well-formed */ char * -TALER_payto_from_reserve (const char *exchange_base_url, - const struct TALER_ReservePublicKeyP *reserve_pub); +TALER_payto_normalize (const char *input); /** @@ -505,5 +645,185 @@ char *strchrnul (const char *s, int c); #endif +/** + * @brief Parses a date information into days after 1970-01-01 (or 0) + * + * The input MUST be of the form + * + * 1) YYYY-MM-DD, representing a valid date + * 2) YYYY-MM-00, representing a valid month in a particular year + * 3) YYYY-00-00, representing a valid year. + * + * In the cases 2) and 3) the out parameter is set to the beginning of the + * time, f.e. 1950-00-00 == 1950-01-01 and 1888-03-00 == 1888-03-01 + * + * The output will set to the number of days after 1970-01-01 or 0, if the input + * represents a date belonging to the largest allowed age group. + * + * @param in Input string representation of the date + * @param mask Age mask + * @param[out] out Where to write the result + * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise + */ +enum GNUNET_GenericReturnValue +TALER_parse_coarse_date ( + const char *in, + const struct TALER_AgeMask *mask, + uint32_t *out); + + +/** + * @brief Parses a string as a list of age groups. + * + * The string must consist of a colon-separated list of increasing integers + * between 0 and 31. Each entry represents the beginning of a new age group. + * F.e. the string + * + * "8:10:12:14:16:18:21" + * + * represents the following list of eight age groups: + * + * | Group | Ages | + * | -----:|:------------- | + * | 0 | 0, 1, ..., 7 | + * | 1 | 8, 9 | + * | 2 | 10, 11 | + * | 3 | 12, 13 | + * | 4 | 14, 15 | + * | 5 | 16, 17 | + * | 6 | 18, 19, 20 | + * | 7 | 21, ... | + * + * which is then encoded as a bit mask with the corresponding bits set: + * + * 31 24 16 8 0 + * | | | | | + * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1 + * + * @param groups String representation of age groups + * @param[out] mask Mask representation for age restriction. + * @return Error, if age groups were invalid, OK otherwise. + */ +enum GNUNET_GenericReturnValue +TALER_parse_age_group_string ( + const char *groups, + struct TALER_AgeMask *mask); + + +/** + * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21" + * + * NOTE: This function uses a static buffer. It is not safe to call this + * function concurrently. + * + * @param mask Age mask + * @return String representation of the age mask. + * Can be used as value in the TALER config. + */ +const char * +TALER_age_mask_to_string ( + const struct TALER_AgeMask *mask); + + +/** + * @brief returns the age group of a given age for a given age mask + * + * @param mask Age mask + * @param age The given age + * @return age group + */ +uint8_t +TALER_get_age_group ( + const struct TALER_AgeMask *mask, + uint8_t age); + + +/** + * @brief Parses a JSON object { "age_groups": "a:b:...y:z" }. + * + * @param root is the json object + * @param[out] mask on success, will contain the age mask + * @return #GNUNET_OK on success and #GNUNET_SYSERR on failure. + */ +enum GNUNET_GenericReturnValue +TALER_JSON_parse_age_groups (const json_t *root, + struct TALER_AgeMask *mask); + + +/** + * @brief Return the lowest age in the corresponding group for a given age + * according the given age mask. + * + * @param mask age mask + * @param age age to check + * @return lowest age in corresponding age group + */ +uint8_t +TALER_get_lowest_age ( + const struct TALER_AgeMask *mask, + uint8_t age); + + +/** + * @brief Get the lowest age for the largest age group + * + * @param mask the age mask + * @return lowest age for the largest age group + */ +#define TALER_adult_age(mask) \ + sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1 + +/** + * Handle to an external process that will assist + * with some JSON-to-JSON conversion. + */ +struct TALER_JSON_ExternalConversion; + +/** + * Type of a callback that receives a JSON @a result. + * + * @param cls closure + * @param status_type how did the process die + * @param code termination status code from the process + * @param result some JSON result, NULL if we failed to get an JSON output + */ +typedef void +(*TALER_JSON_JsonCallback) (void *cls, + enum GNUNET_OS_ProcessStatusType status_type, + unsigned long code, + const json_t *result); + + +/** + * Launch some external helper @a binary to convert some @a input + * and eventually call @a cb with the result. + * + * @param input JSON to serialize and pass to the helper process + * @param cb function to call on the result + * @param cb_cls closure for @a cb + * @param binary name of the binary to execute + * @param ... NULL-terminated list of arguments for the @a binary, + * usually starting with again the name of the binary + * @return handle to cancel the operation (and kill the helper) + */ +struct TALER_JSON_ExternalConversion * +TALER_JSON_external_conversion_start (const json_t *input, + TALER_JSON_JsonCallback cb, + void *cb_cls, + const char *binary, + ...); + +/** + * Abort external conversion, killing the process and preventing + * the callback from being called. Must not be called after the + * callback was invoked. + * + * @param[in] ec external conversion handle to cancel + */ +void +TALER_JSON_external_conversion_stop ( + struct TALER_JSON_ExternalConversion *ec); + +#undef __TALER_UTIL_LIB_H_INSIDE__ #endif |