set_extensions and postgres-handler implemented
This commit is contained in:
parent
ef4238874f
commit
d0d7d78336
@ -42,7 +42,7 @@ struct Extension
|
||||
// configuration for the age restriction
|
||||
struct TALER_AgeMask mask;
|
||||
|
||||
/* TODO oec - peer2peer config */
|
||||
/* TODO oec - add peer2peer config */
|
||||
};
|
||||
};
|
||||
|
||||
@ -77,9 +77,46 @@ set_extensions (void *cls,
|
||||
struct MHD_Connection *connection,
|
||||
MHD_RESULT *mhd_ret)
|
||||
{
|
||||
// struct SetExtensionContext *sec = cls;
|
||||
struct SetExtensionsContext *sec = cls;
|
||||
|
||||
/* save the configurations of all extensions */
|
||||
for (uint32_t i = 0; i<sec->num_extensions; i++)
|
||||
{
|
||||
struct Extension *ext = &sec->extensions[i];
|
||||
struct TALER_MasterSignatureP *sig = &sec->extensions_sigs[i];
|
||||
enum GNUNET_DB_QueryStatus qs;
|
||||
char *config;
|
||||
|
||||
config = json_dumps (ext->config_json, JSON_COMPACT | JSON_SORT_KEYS);
|
||||
if (NULL == config)
|
||||
{
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_JSON_INVALID,
|
||||
"convert configuration to string");
|
||||
return GNUNET_DB_STATUS_SOFT_ERROR; /* FIXME: right error? */
|
||||
}
|
||||
|
||||
qs = TEH_plugin->set_extension_config (
|
||||
TEH_plugin->cls,
|
||||
TEH_extensions[ext->type].name,
|
||||
config,
|
||||
sig);
|
||||
|
||||
if (qs < 0)
|
||||
{
|
||||
if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
|
||||
return qs;
|
||||
GNUNET_break (0);
|
||||
*mhd_ret = TALER_MHD_reply_with_error (connection,
|
||||
MHD_HTTP_INTERNAL_SERVER_ERROR,
|
||||
TALER_EC_GENERIC_DB_STORE_FAILED,
|
||||
"save extension configuration");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO oec
|
||||
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; /* only 'success', so >=0, matters here */
|
||||
}
|
||||
|
||||
@ -99,7 +136,6 @@ TEH_handler_management_post_extensions (
|
||||
&extensions_sigs),
|
||||
GNUNET_JSON_spec_end ()
|
||||
};
|
||||
bool ok;
|
||||
MHD_RESULT ret;
|
||||
|
||||
{
|
||||
@ -123,7 +159,7 @@ TEH_handler_management_post_extensions (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"array expected for extensions and extensions_sig");
|
||||
"array expected for extensions and extensions_sigs");
|
||||
}
|
||||
|
||||
sec.num_extensions = json_array_size (extensions_sigs);
|
||||
@ -135,7 +171,7 @@ TEH_handler_management_post_extensions (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"arrays extensions and extensions_sig are not of equal size");
|
||||
"arrays extensions and extensions_sigs are not of equal size");
|
||||
}
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
@ -145,11 +181,9 @@ TEH_handler_management_post_extensions (
|
||||
struct Extension);
|
||||
sec.extensions_sigs = GNUNET_new_array (sec.num_extensions,
|
||||
struct TALER_MasterSignatureP);
|
||||
ok = true;
|
||||
|
||||
for (unsigned int i = 0; i<sec.num_extensions; i++)
|
||||
{
|
||||
|
||||
// 1. parse the extension
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
@ -170,17 +204,15 @@ TEH_handler_management_post_extensions (
|
||||
if (GNUNET_SYSERR == res)
|
||||
{
|
||||
ret = MHD_NO; /* hard failure */
|
||||
ok = false;
|
||||
break;
|
||||
goto CLEANUP;
|
||||
}
|
||||
if (GNUNET_NO == res)
|
||||
{
|
||||
ret = MHD_YES;
|
||||
ok = false;
|
||||
break;
|
||||
goto CLEANUP;;
|
||||
}
|
||||
|
||||
// Make sure name refers to a supported extension
|
||||
/* Make sure name refers to a supported extension */
|
||||
{
|
||||
bool found = false;
|
||||
for (unsigned int k = 0; k < TALER_Extension_Max; k++)
|
||||
@ -197,25 +229,22 @@ TEH_handler_management_post_extensions (
|
||||
|
||||
if (! found)
|
||||
{
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
GNUNET_JSON_parse_free (ispec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid extension type");
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a JSON object for the extension. Increment its refcount and
|
||||
// free the parser.
|
||||
// TODO: is this correct?
|
||||
/* We have a JSON object for the extension.
|
||||
* Increment its refcount and free the parser.
|
||||
* TODO: is this correct? */
|
||||
json_incref (sec.extensions[i].config_json);
|
||||
GNUNET_JSON_parse_free (ispec);
|
||||
|
||||
// Make sure the config is sound
|
||||
/* Make sure the config is sound */
|
||||
{
|
||||
switch (sec.extensions[i].type)
|
||||
{
|
||||
@ -224,34 +253,33 @@ TEH_handler_management_post_extensions (
|
||||
sec.extensions[i].config_json,
|
||||
&sec.extensions[i].mask))
|
||||
{
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid mask for age restriction");
|
||||
goto CLEANUP;
|
||||
}
|
||||
break;
|
||||
|
||||
case TALER_Extension_Peer2Peer: /* TODO */
|
||||
ok = false;
|
||||
case TALER_Extension_Peer2Peer:
|
||||
/* TODO */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"peer2peer not yet supported in handler for /management/extensions\n");
|
||||
ret = MHD_NO;
|
||||
goto BREAK;
|
||||
goto CLEANUP;
|
||||
|
||||
default:
|
||||
/* not reachable */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"shouldn't be reached in handler for /management/extensions\n");
|
||||
ok = false;
|
||||
ret = MHD_NO;
|
||||
goto BREAK;
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. parse the signature
|
||||
// 2. parse and verify the signature
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
struct GNUNET_JSON_Specification ispec[] = {
|
||||
@ -268,20 +296,16 @@ TEH_handler_management_post_extensions (
|
||||
if (GNUNET_SYSERR == res)
|
||||
{
|
||||
ret = MHD_NO; /* hard failure */
|
||||
ok = false;
|
||||
break;
|
||||
goto CLEANUP;
|
||||
}
|
||||
if (GNUNET_NO == res)
|
||||
{
|
||||
ret = MHD_YES;
|
||||
ok = false;
|
||||
break;
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. verify the signature
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
/* verify the signature */
|
||||
res = GNUNET_SYSERR;
|
||||
|
||||
switch (sec.extensions[i].type)
|
||||
{
|
||||
@ -290,53 +314,40 @@ TEH_handler_management_post_extensions (
|
||||
sec.extensions[i].mask,
|
||||
&TEH_master_public_key,
|
||||
&sec.extensions_sigs[i]);
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid signature for age mask");
|
||||
}
|
||||
break;
|
||||
|
||||
case TALER_Extension_Peer2Peer: /* TODO */
|
||||
case TALER_Extension_Peer2Peer:
|
||||
/* TODO */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Peer2peer not yet supported in handler for /management/extensions\n");
|
||||
ok = false;
|
||||
ret = MHD_NO;
|
||||
goto BREAK;
|
||||
goto CLEANUP;
|
||||
|
||||
default:
|
||||
/* not reachable */
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"shouldn't be reached in handler for /management/extensions\n");
|
||||
ok = false;
|
||||
ret = MHD_NO;
|
||||
/* not reachable */
|
||||
goto BREAK;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
if (GNUNET_OK != res)
|
||||
{
|
||||
ret = TALER_MHD_reply_with_error (
|
||||
connection,
|
||||
MHD_HTTP_BAD_REQUEST,
|
||||
TALER_EC_GENERIC_PARAMETER_MALFORMED,
|
||||
"invalid signature for extension");
|
||||
goto CLEANUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BREAK:
|
||||
if (! ok)
|
||||
{
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||
"Failure to handle /management/extensions\n");
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} /* for-loop */
|
||||
|
||||
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
||||
"Received %u extensions\n",
|
||||
sec.num_extensions);
|
||||
|
||||
// now run the transaction to persist the configurations
|
||||
{
|
||||
enum GNUNET_GenericReturnValue res;
|
||||
|
||||
@ -347,19 +358,29 @@ BREAK:
|
||||
&set_extensions,
|
||||
&sec);
|
||||
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
if (GNUNET_SYSERR == res)
|
||||
return ret;
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
return TALER_MHD_reply_static (
|
||||
ret = TALER_MHD_reply_static (
|
||||
connection,
|
||||
MHD_HTTP_NO_CONTENT,
|
||||
NULL,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
CLEANUP:
|
||||
for (unsigned int i = 0; i < sec.num_extensions; i++)
|
||||
{
|
||||
if (NULL != sec.extensions[i].config_json)
|
||||
{
|
||||
json_decref (sec.extensions[i].config_json);
|
||||
}
|
||||
}
|
||||
GNUNET_free (sec.extensions);
|
||||
GNUNET_free (sec.extensions_sigs);
|
||||
GNUNET_JSON_parse_free (spec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2743,6 +2743,23 @@ prepare_statements (struct PostgresClosure *pg)
|
||||
" AND start_row=$2"
|
||||
" AND end_row=$3",
|
||||
3),
|
||||
/* Used in #postgres_set_extension_config */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"set_extension_config",
|
||||
"WITH upsert AS "
|
||||
" (UPDATE extensions "
|
||||
" SET config=$2 "
|
||||
" config_sig=$3 "
|
||||
" WHERE name=$1 RETURNING *) "
|
||||
"INSERT INTO extensions (config, config_sig) VALUES ($2, $3) "
|
||||
"WHERE NOT EXISTS (SELECT * FROM upsert);",
|
||||
3),
|
||||
/* Used in #postgres_get_extension_config */
|
||||
GNUNET_PQ_make_prepare (
|
||||
"get_extension_config",
|
||||
"SELECT (config) FROM extensions"
|
||||
" WHERE name=$1;",
|
||||
1),
|
||||
GNUNET_PQ_PREPARED_STATEMENT_END
|
||||
};
|
||||
|
||||
@ -3513,7 +3530,7 @@ postgres_iterate_active_signkeys (void *cls,
|
||||
void *cb_cls)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
struct GNUNET_TIME_Absolute now = {0};
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_absolute_time (&now),
|
||||
GNUNET_PQ_query_param_end
|
||||
@ -4470,6 +4487,8 @@ compute_shard (const struct TALER_MerchantPublicKeyP *merchant_pub)
|
||||
* Perform deposit operation, checking for sufficient balance
|
||||
* of the coin and possibly persisting the deposit details.
|
||||
*
|
||||
* FIXME: parameters missing in description!
|
||||
*
|
||||
* @param cls the `struct PostgresClosure` with the plugin-specific state
|
||||
* @param deposit deposit operation details
|
||||
* @param known_coin_id row of the coin in the known_coins table
|
||||
@ -5361,7 +5380,7 @@ postgres_get_ready_deposit (void *cls,
|
||||
void *deposit_cb_cls)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_TIME_Absolute now;
|
||||
struct GNUNET_TIME_Absolute now = {0};
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_absolute_time (&now),
|
||||
GNUNET_PQ_query_param_uint64 (&start_shard_row),
|
||||
@ -11394,6 +11413,67 @@ postgres_delete_shard_locks (void *cls)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called to save the configuration of an extension
|
||||
* (age-restriction, peer2peer, ...)
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param config JSON object of the configuration as string
|
||||
* @param config_sig signature of the configuration by the offline master key
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
postgres_set_extension_config (void *cls,
|
||||
const char *extension_name,
|
||||
const char *config,
|
||||
const struct TALER_MasterSignatureP *config_sig)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_string (extension_name),
|
||||
GNUNET_PQ_query_param_string (config),
|
||||
GNUNET_PQ_query_param_auto_from_type (config_sig),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
|
||||
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
|
||||
"set_extension_config",
|
||||
params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called to get the configuration of an extension
|
||||
* (age-restriction, peer2peer, ...)
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param[out] config JSON object of the configuration as string
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
postgres_get_extension_config (void *cls,
|
||||
const char *extension_name,
|
||||
char **config)
|
||||
{
|
||||
struct PostgresClosure *pg = cls;
|
||||
struct GNUNET_PQ_QueryParam params[] = {
|
||||
GNUNET_PQ_query_param_string (extension_name),
|
||||
GNUNET_PQ_query_param_end
|
||||
};
|
||||
struct GNUNET_PQ_ResultSpec rs[] = {
|
||||
GNUNET_PQ_result_spec_string ("config", config),
|
||||
GNUNET_PQ_result_spec_end
|
||||
};
|
||||
|
||||
return GNUNET_PQ_eval_prepared_singleton_select (pg->conn,
|
||||
"get_extension_config",
|
||||
params,
|
||||
rs);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize Postgres database subsystem.
|
||||
*
|
||||
@ -11628,6 +11708,10 @@ libtaler_plugin_exchangedb_postgres_init (void *cls)
|
||||
= &postgres_release_revolving_shard;
|
||||
plugin->delete_shard_locks
|
||||
= &postgres_delete_shard_locks;
|
||||
plugin->set_extension_config
|
||||
= &postgres_set_extension_config;
|
||||
plugin->get_extension_config
|
||||
= &postgres_get_extension_config;
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
@ -4025,8 +4025,35 @@ struct TALER_EXCHANGEDB_Plugin
|
||||
(*delete_shard_locks)(void *cls);
|
||||
|
||||
/**
|
||||
* TODO-oec: add function for adding extension config
|
||||
* Function called to save the configuration of an extension
|
||||
* (age-restriction, peer2peer, ...)
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param config JSON object of the configuration as string
|
||||
* @param config_sig signature of the configuration by the offline master key
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*set_extension_config)(void *cls,
|
||||
const char *extension_name,
|
||||
const char *config,
|
||||
const struct TALER_MasterSignatureP *config_sig);
|
||||
|
||||
/**
|
||||
* Function called to retrieve the configuration of an extension
|
||||
* (age-restriction, peer2peer, ...)
|
||||
*
|
||||
* @param cls the @e cls of this struct with the plugin-specific state
|
||||
* @param extension_name the name of the extension
|
||||
* @param[out] config JSON object of the configuration as string
|
||||
* @param[out] config_sig signature of the configuration by the master key
|
||||
* @return transaction status code
|
||||
*/
|
||||
enum GNUNET_DB_QueryStatus
|
||||
(*get_extension_config)(void *cls,
|
||||
const char *extension_name,
|
||||
char **config);
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user