LCOV - code coverage report
Current view: top level - extensions/age_restriction - age_restriction.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 64 59.4 %
Date: 2025-06-05 21:03:14 Functions: 3 5 60.0 %

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

Generated by: LCOV version 1.16