first steps for offline tool to handle extensions
This commit is contained in:
parent
6bfbe260c7
commit
601c18caba
@ -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,
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user