diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h index 0ef69a78d..1ef97b2e9 100644 --- a/src/include/taler_extensions.h +++ b/src/include/taler_extensions.h @@ -1,18 +1,18 @@ /* - This file is part of TALER - Copyright (C) 2014-2021 Taler Systems SA + This file is part of TALER + Copyright (C) 2014-2021 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 - Foundation; either version 3, or (at your option) any later version. + 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 + Foundation; either version 3, or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see -*/ + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + */ /** * @file include/taler_extensions.h * @brief Interface for extensions @@ -21,14 +21,51 @@ #ifndef TALER_EXTENSIONS_H #define TALER_EXTENSIONS_H +#include + + +#define TALER_EXTENSION_SECTION_PREFIX "exchange-extension-" + +enum TALER_EXTENSION_ReturnValue +{ + TALER_EXTENSION_OK = 0, + TALER_EXTENSION_ERROR_PARSING = 1, + TALER_EXTENSION_ERROR_INVALID = 2, + TALER_EXTENSION_ERROR_SYS = 3 +}; + + +/* + * TALER Age Restriction Extensions + */ + +#define TALER_EXTENSION_SECTION_AGE_RESTRICTION TALER_EXTENSION_SECTION_PREFIX \ + "agerestriction" + +/** + * The default age mask represents the age groups + * 0-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-20, 21-... + */ +#define TALER_EXTENSION_DEFAULT_AGE_MASK (1 | 1 << 8 | 1 << 10 | 1 << 12 | 1 << \ + 14 | 1 << 16 | 1 << 18 | 1 << 21) + +/** + * @param groups String representation of age groups, like: "8:10:12:14:16:18:21" + * @param[out] mask Mask representation for age restriction. + * @return Error, if age groups were invalid, OK otherwise. + */ +enum TALER_EXTENSION_ReturnValue +TALER_parse_age_group_string (char *groups, + struct TALER_AgeMask *mask); + /** * * @param cfg - * @param[out] mask for age restriction + * @param[out] mask for age restriction, will be set to 0 if age restriction is disabled. * @return Error if extension for age restriction was set but age groups were * invalid, OK otherwise. */ -enum GNUNET_GenericReturnValue +enum TALER_EXTENSION_ReturnValue TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle *cfg, struct TALER_AgeMask *mask); diff --git a/src/util/extension_age_restriction.c b/src/util/extension_age_restriction.c index dbb4f3e23..6bbfde04c 100644 --- a/src/util/extension_age_restriction.c +++ b/src/util/extension_age_restriction.c @@ -1,18 +1,18 @@ /* - This file is part of TALER - Copyright (C) 2014-2020 Taler Systems SA + This file is part of TALER + Copyright (C) 2014-2020 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 - Foundation; either version 3, or (at your option) any later version. + 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 + Foundation; either version 3, or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along with - TALER; see the file COPYING. If not, see -*/ + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + */ /** * @file extension_age_restriction.c * @brief Utility functions regarding age restriction @@ -20,29 +20,160 @@ */ #include "platform.h" #include "taler_util.h" +#include "taler_extensions.h" +#include "stdint.h" /** * - * @param cfg - * @param[out] mask for age restriction - * @return Error if extension for age restriction was set but age groups were + * @param cfg Handle to the GNUNET configuration + * @param[out] Mask for age restriction. Will be 0 if age restriction was not enabled in the config. + * @return Error if extension for age restriction was set, but age groups were * invalid, OK otherwise. */ -enum GNUNET_GenericReturnValue +enum TALER_EXTENSION_ReturnValue TALER_get_age_mask (const struct GNUNET_CONFIGURATION_Handle *cfg, struct TALER_AgeMask *mask) { - /* FIXME-Oec: - * - * - Detect if age restriction is enabled in config - * - if not, return 0 mask - * - else, parse age group and serialize into mask - * - return Error on - * - * */ - mask->mask = 0; - return GNUNET_OK; + char *groups; + enum TALER_EXTENSION_ReturnValue ret = TALER_EXTENSION_ERROR_SYS; + + if ((GNUNET_NO == GNUNET_CONFIGURATION_have_value (cfg, + TALER_EXTENSION_SECTION_AGE_RESTRICTION, + "ENABLED")) || + (GNUNET_NO == GNUNET_CONFIGURATION_get_value_yesno (cfg, + TALER_EXTENSION_SECTION_AGE_RESTRICTION, + "ENABLED"))) + { + /* Age restriction is not enabled */ + mask->mask = 0; + return TALER_EXTENSION_OK; + } + + /* Age restriction is enabled, extract age groups */ + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, + TALER_EXTENSION_SECTION_AGE_RESTRICTION, + "AGE_GROUPS", + &groups)) + { + /* FIXME: log error? */ + return TALER_EXTENSION_ERROR_SYS; + } + if (groups == NULL) + { + /* No groups defined in config, return default_age_mask */ + mask->mask = TALER_EXTENSION_DEFAULT_AGE_MASK; + return TALER_EXTENSION_OK; + } + + ret = TALER_parse_age_group_string (groups, mask); + GNUNET_free (groups); + return ret; +} + + +/** + * @param groups String representation of the age groups. Must be of the form + * a:b:...:n:m + * with + * 0 < a < b <...< n < m < 32 + * @param[out] mask Bit representation of the age groups. + * @return Error if string was invalid, OK otherwise. + */ +enum TALER_EXTENSION_ReturnValue +TALER_parse_age_group_string (char *groups, + struct TALER_AgeMask *mask) +{ + enum TALER_EXTENSION_ReturnValue ret = TALER_EXTENSION_ERROR_SYS; + char *pos; + int prev = -1; + unsigned int val; + char dummy; + + while (1) + { + pos = strchr (groups, ':'); + if (NULL != pos) + { + *pos = 0; + } + + if (1 != sscanf (groups, + "%u%c", + &val, + &dummy)) + { + /* Invalid input */ + mask->mask = 0; + ret = TALER_EXTENSION_ERROR_PARSING; + break; + } + else if ((0 >= val) || (32 <= val) || (prev >= val)) + { + /* Invalid value */ + mask->mask = 0; + ret = TALER_EXTENSION_ERROR_INVALID; + break; + } + + /* Set the corresponding bit in the mask */ + mask->mask |= 1 << val; + + if (NULL == pos) + { + /* We reached the end. Mark zeroth age-group and exit. */ + mask->mask |= 1; + ret = TALER_EXTENSION_OK; + break; + } + + prev = val; + groups = pos + 1; + } + + return ret; +} + + +/** + * @param mask Age mask + * @return String representation of the age mask, allocated by GNUNET_malloc. + * Can be used as value in the TALER config. + */ +char * +TALER_age_mask_to_string (struct TALER_AgeMask *m) +{ + uint32_t mask = m->mask; + unsigned int n = 0; + char *buf = GNUNET_malloc (32 * 3); // max characters possible + char *pos = buf; + + if (NULL == buf) + { + return buf; + } + + while (mask != 0) + { + mask >>= 1; + n++; + if (0 == (mask & 1)) + { + continue; + } + + if (n > 9) + { + *(pos++) = '0' + n / 10; + } + *(pos++) = '0' + n % 10; + + if (0 != (mask >> 1)) + { + *(pos++) = ':'; + } + } + return buf; }