exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

age_restriction.c (7422B)


      1 /*
      2    This file is part of TALER
      3    Copyright (C) 2021-2022 Taler Systems SA
      4 
      5    TALER is free software; you can redistribute it and/or modify it under the
      6    terms of the GNU General Public License as published by the Free Software
      7    Foundation; either version 3, or (at your option) any later version.
      8 
      9    TALER 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 General Public License for more details.
     12 
     13    You should have received a copy of the GNU General Public License along with
     14    TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 /**
     17  * @file age_restriction.c
     18  * @brief Utility functions regarding age restriction
     19  * @author Özgür Kesim
     20  */
     21 #include "taler/taler_util.h"
     22 #include "taler/taler_extensions.h"
     23 #include "stdint.h"
     24 
     25 /* ==================================================
     26  *
     27  * Age Restriction  TALER_Extension implementation
     28  *
     29  * ==================================================
     30  */
     31 
     32 /**
     33  * @brief local configuration
     34  */
     35 
     36 static struct TALER_AgeRestrictionConfig AR_config = {0};
     37 
     38 /**
     39  * @brief implements the TALER_Extension.disable interface.
     40  *
     41  * @param ext Pointer to the current extension
     42  */
     43 static void
     44 age_restriction_disable (
     45   struct TALER_Extension *ext)
     46 {
     47   if (NULL == ext)
     48     return;
     49 
     50   ext->enabled = false;
     51   ext->config = NULL;
     52 
     53   AR_config.mask.bits = 0;
     54   AR_config.num_groups = 0;
     55 }
     56 
     57 
     58 /**
     59  * @brief implements the TALER_Extension.load_config interface.
     60  *
     61  * @param ext if NULL, only tests the configuration
     62  * @param jconfig the configuration as json
     63  */
     64 static enum GNUNET_GenericReturnValue
     65 age_restriction_load_config (
     66   const json_t *jconfig,
     67   struct TALER_Extension *ext)
     68 {
     69   struct TALER_AgeMask mask = {0};
     70   enum GNUNET_GenericReturnValue ret;
     71 
     72   ret = TALER_JSON_parse_age_groups (jconfig, &mask);
     73   if (GNUNET_OK != ret)
     74     return ret;
     75 
     76   /* only testing the parser */
     77   if (ext == NULL)
     78     return GNUNET_OK;
     79 
     80   if (TALER_Extension_AgeRestriction != ext->type)
     81     return GNUNET_SYSERR;
     82 
     83   if (mask.bits > 0)
     84   {
     85     /* if the mask is not zero, the first bit MUST be set */
     86     if (0 == (mask.bits & 1))
     87       return GNUNET_SYSERR;
     88 
     89     AR_config.mask.bits = mask.bits;
     90     AR_config.num_groups = __builtin_popcount (mask.bits) - 1;
     91   }
     92 
     93   ext->config = &AR_config;
     94   ext->enabled = true;
     95 
     96   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
     97               "loaded new age restriction config with age groups: %s\n",
     98               TALER_age_mask_to_string (&mask));
     99 
    100   return GNUNET_OK;
    101 }
    102 
    103 
    104 /**
    105  * @brief implements the TALER_Extension.manifest interface.
    106  *
    107  * @param ext if NULL, only tests the configuration
    108  * @return configuration as json_t* object, maybe NULL
    109  */
    110 static json_t *
    111 age_restriction_manifest (
    112   const struct TALER_Extension *ext)
    113 {
    114   json_t *conf;
    115 
    116   GNUNET_assert (NULL != ext);
    117 
    118   if (NULL == ext->config)
    119   {
    120     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    121                 "age restriction not configured");
    122     return json_null ();
    123   }
    124 
    125   conf = GNUNET_JSON_PACK (
    126     GNUNET_JSON_pack_string ("age_groups",
    127                              TALER_age_mask_to_string (&AR_config.mask))
    128     );
    129   return GNUNET_JSON_PACK (
    130     GNUNET_JSON_pack_bool ("critical",
    131                            ext->critical),
    132     GNUNET_JSON_pack_string ("version",
    133                              ext->version),
    134     GNUNET_JSON_pack_object_steal ("config",
    135                                    conf)
    136     );
    137 }
    138 
    139 
    140 /* The extension for age restriction */
    141 struct TALER_Extension TE_age_restriction = {
    142   .type = TALER_Extension_AgeRestriction,
    143   .name = "age_restriction",
    144   .critical = false,
    145   .version = "1",
    146   .enabled = false, /* disabled per default */
    147   .config = NULL,
    148   .disable = &age_restriction_disable,
    149   .load_config = &age_restriction_load_config,
    150   .manifest = &age_restriction_manifest,
    151 
    152   /* This extension is not a policy extension */
    153   .create_policy_details = NULL,
    154   .policy_get_handler = NULL,
    155   .policy_post_handler = NULL,
    156 };
    157 
    158 
    159 /**
    160  * @brief implements the init() function for GNUNET_PLUGIN_load
    161  *
    162  * @param arg Pointer to the GNUNET_CONFIGURATION_Handle
    163  * @return pointer to TALER_Extension on success or NULL otherwise.
    164  */
    165 void *
    166 libtaler_extension_age_restriction_init (void *arg);
    167 
    168 /* Declaration used to squash compiler warning */
    169 void *
    170 libtaler_extension_age_restriction_init (void *arg)
    171 {
    172   const struct GNUNET_CONFIGURATION_Handle *cfg = arg;
    173   char *groups = NULL;
    174   struct TALER_AgeMask mask = {0};
    175 
    176   if ((GNUNET_YES !=
    177        GNUNET_CONFIGURATION_have_value (cfg,
    178                                         TALER_EXTENSION_SECTION_AGE_RESTRICTION,
    179                                         "ENABLED"))
    180       ||
    181       (GNUNET_YES !=
    182        GNUNET_CONFIGURATION_get_value_yesno (cfg,
    183                                              TALER_EXTENSION_SECTION_AGE_RESTRICTION,
    184                                              "ENABLED")))
    185   {
    186     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    187                 "[age restriction] no section %s found in configuration\n",
    188                 TALER_EXTENSION_SECTION_AGE_RESTRICTION);
    189 
    190     return NULL;
    191   }
    192 
    193   /* Age restriction is enabled, extract age groups */
    194   if ((GNUNET_YES ==
    195        GNUNET_CONFIGURATION_have_value (cfg,
    196                                         TALER_EXTENSION_SECTION_AGE_RESTRICTION,
    197                                         "AGE_GROUPS"))
    198       &&
    199       (GNUNET_YES !=
    200        GNUNET_CONFIGURATION_get_value_string (cfg,
    201                                               TALER_EXTENSION_SECTION_AGE_RESTRICTION,
    202                                               "AGE_GROUPS",
    203                                               &groups)))
    204   {
    205     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    206                 "[age restriction] AGE_GROUPS in %s is not a string\n",
    207                 TALER_EXTENSION_SECTION_AGE_RESTRICTION);
    208 
    209     return NULL;
    210   }
    211 
    212   if (NULL == groups)
    213     groups = GNUNET_strdup (TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_GROUPS);
    214 
    215   if (GNUNET_OK != TALER_parse_age_group_string (groups, &mask))
    216   {
    217     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    218                 "[age restriction] couldn't parse age groups: '%s'\n",
    219                 groups);
    220     return NULL;
    221   }
    222 
    223   AR_config.mask = mask;
    224   AR_config.num_groups = __builtin_popcount (mask.bits) - 1;   /* no underflow, first bit always set */
    225 
    226   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    227               "[age restriction] setting age mask to %s with #groups: %d\n",
    228               TALER_age_mask_to_string (&AR_config.mask),
    229               __builtin_popcount (AR_config.mask.bits) - 1);
    230 
    231   TE_age_restriction.config = &AR_config;
    232 
    233   /* Note: we do now have TE_age_restriction_config set, however the extension
    234    * is not yet enabled! For age restriction to become active, load_config must
    235    * have been called. */
    236 
    237   GNUNET_free (groups);
    238   return &TE_age_restriction;
    239 }
    240 
    241 
    242 /**
    243  * @brief implements the done() function for GNUNET_PLUGIN_load
    244  *
    245  * @param arg unused
    246  * @return pointer to TALER_Extension on success or NULL otherwise.
    247  */
    248 void *
    249 libtaler_extension_age_restriction_done (void *arg);
    250 
    251 /* Declaration used to squash compiler warning */
    252 void *
    253 libtaler_extension_age_restriction_done (void *arg)
    254 {
    255   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    256               "[age restriction] disabling and unloading");
    257   AR_config.mask.bits = 0;
    258   AR_config.num_groups = 0;
    259   return NULL;
    260 }
    261 
    262 
    263 /* end of age_restriction.c */