first steps for offline tool to handle extensions

This commit is contained in:
Özgür Kesim 2022-01-18 12:21:05 +01:00
parent 6bfbe260c7
commit 601c18caba
Signed by: oec
GPG Key ID: 3D76A56D79EDD9D7
2 changed files with 269 additions and 2 deletions

View File

@ -20,8 +20,10 @@
*/
#include <platform.h>
#include <gnunet/gnunet_json_lib.h>
#include <gnunet/gnunet_util_lib.h>
#include "taler_json_lib.h"
#include "taler_exchange_service.h"
#include "taler_extensions.h"
/**
* Name of the input for the 'sign' and 'show' operation.
@ -3314,6 +3316,265 @@ do_setup (char *const *args)
}
struct extension
{
char *name;
bool critical;
char *version;
void *config;
enum GNUNET_GenericReturnValue (*parse_config)(struct extension *this,
const char *section);
json_t *(*config_json)(const struct extension *this);
};
static enum GNUNET_GenericReturnValue
age_restriction_parse_config (struct extension *this, const char *section)
{
char *age_groups;
struct TALER_AgeMask *mask = GNUNET_malloc (sizeof(struct TALER_AgeMask));
if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (kcfg,
section,
"AGE_GROUPS",
&age_groups))
goto ERROR;
if (GNUNET_OK != TALER_parse_age_group_string (age_groups, mask))
goto ERROR;
this->config = mask;
return GNUNET_OK;
ERROR:
GNUNET_free (mask);
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"AGE_GROUPS");
test_shutdown ();
global_ret = EXIT_NOTCONFIGURED;
return GNUNET_SYSERR;
}
static json_t *
age_restriction_json (const struct extension *this)
{
char *groups = TALER_age_mask_to_string (this->config);
return GNUNET_JSON_PACK (
GNUNET_JSON_pack_bool ("critical",
this->critical),
GNUNET_JSON_pack_string ("version",
this->version),
GNUNET_JSON_pack_string ("age_groups", groups)
);
}
static struct extension extensions[] = {
{
.name = "age-restriction",
.version = "1",
.parse_config = &age_restriction_parse_config,
.config_json = &age_restriction_json,
},
/* TODO: add p2p here */
{0},
};
static const struct extension*
get_extension (const char *extension)
{
for (const struct extension *known = extensions; NULL != known->name; known++)
{
if (0 == strncasecmp (extension, known->name, strlen (known->name)))
return known;
}
return NULL;
}
static void
show_extensions (void *cls, const char *section)
{
if (0 != global_ret)
{
return;
}
if (0 == strncasecmp (section,
"exchange-extension-",
sizeof("exchange-extension-") - 1))
{
const char *name = section + sizeof("exchange-extension-") - 1;
const struct extension *extension = get_extension (name);
enum GNUNET_GenericReturnValue ret;
if (NULL == extension)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unsupported extension `%s` (section [%s]).\n", name,
section);
test_shutdown ();
global_ret = EXIT_INVALIDARGUMENT;
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "found extension %s\n", name);
{
bool enabled = (GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_yesno (
kcfg, section, "ENABLED"));
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"\textension is %s\n",
enabled?"ENABLED":"DISABLED");
if (! enabled)
return;
ret = extension->parse_config ((struct extension *) extension, section);
if (GNUNET_OK != ret)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Couldn't parse configuration for extension `%s` (section [%s]).\n",
name,
section);
test_shutdown ();
global_ret = EXIT_INVALIDARGUMENT;
return;
}
json_t *cfg = extension->config_json (extension);
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"\tconfig: %s\n",
json_dumps (cfg, JSON_INDENT (2)));
return;
}
}
}
static void
sign_extensions (void *cls, const char *section)
{
if (0 != global_ret)
{
return;
}
if (0 == strncasecmp (section,
"exchange-extension-",
sizeof("exchange-extension-") - 1))
{
const char *name = section + sizeof("exchange-extension-") - 1;
const struct extension *extension = get_extension (name);
if (NULL == extension)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"Unsupported extension `%s` (section [%s]).\n", name,
section);
test_shutdown ();
global_ret = EXIT_INVALIDARGUMENT;
return;
}
if (GNUNET_YES ==
GNUNET_CONFIGURATION_get_value_yesno (
kcfg, section, "ENABLED"))
{
// TODO
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "TODO signing extension %s\n",
name);
}
}
}
/*
* Print the current extensions as configured
*/
static void
do_extensions_show (char *const *args)
{
GNUNET_CONFIGURATION_iterate_sections (kcfg,
&show_extensions,
NULL);
}
static void
do_extensions_sign (char *const *args)
{
GNUNET_CONFIGURATION_iterate_sections (kcfg,
&sign_extensions,
NULL);
}
static void
do_work_extensions (char *const *args)
{
struct SubCommand cmds[] = {
{
.name = "show",
.help =
"show the extensions in the Taler-config and their configured parameters",
.cb = &do_extensions_show
},
{
.name = "sign",
.help =
"sign the configuration of the extensions and publish it with the exchange",
.cb = &do_extensions_sign
},
{
.name = NULL,
}
};
if (NULL == args[0])
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
"You must provide a subcommand: `show` or `sign`.\n");
test_shutdown ();
global_ret = EXIT_INVALIDARGUMENT;
return;
}
nxt = NULL;
for (unsigned int i = 0; NULL != cmds[i].name; i++)
{
if (0 == strcasecmp (cmds[i].name,
args[0]))
{
cmds[i].cb (&args[1]);
return;
}
}
if (0 != strcasecmp ("help",
args[0]))
{
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Unexpected command `%s'\n",
args[0]);
global_ret = EXIT_INVALIDARGUMENT;
}
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"Supported subcommands:\n");
for (unsigned int i = 0; NULL != cmds[i].name; i++)
{
GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
"- %s: %s\n",
cmds[i].name,
cmds[i].help);
}
}
static void
work (void *cls)
{
@ -3390,6 +3651,11 @@ work (void *cls)
"upload operation result to exchange (to be performed online!)",
.cb = &do_upload
},
{
.name = "extensions",
.help = "subcommands for extension handling",
.cb = &do_work_extensions
},
/* list terminator */
{
.name = NULL,

View File

@ -77,9 +77,10 @@ WIRE_GATEWAY_URL = "http://localhost:9081/2/"
[bank]
HTTP_PORT = 9081
[exchange-extension-age_restriction]
# Enabled extensions
[exchange-extension-age-restriction]
ENABLED = YES
AGE_RESTRICTION = "8:14:16"
AGE_GROUPS = "8:10:12:14:16:18:21"
# Sections starting with "coin_" specify which denominations
# the exchange should support (and their respective fee structure)