From 441d1a5915beb96556541292f95f8d3a434e1d9a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 17 Feb 2021 20:48:28 +0100 Subject: fix account re-enable issue, related to #6755, but not exactly --- src/backend/taler-merchant-httpd.h | 5 +++ ...ler-merchant-httpd_private-patch-instances-ID.c | 38 +++++++++++++++++----- .../taler-merchant-httpd_private-post-orders.c | 2 +- src/backenddb/plugin_merchantdb_postgres.c | 34 +++++++++++++++++-- src/include/taler_merchantdb_plugin.h | 12 +++++++ 5 files changed, 80 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h index c3300e42..50badbb1 100644 --- a/src/backend/taler-merchant-httpd.h +++ b/src/backend/taler-merchant-httpd.h @@ -75,6 +75,11 @@ struct TMH_WireMethod */ bool deleting; + /** + * Are we currently in a transaction to enable this account? + */ + bool enabling; + }; diff --git a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c index 4590e6c5..62dc77a4 100644 --- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c +++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c @@ -193,7 +193,7 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, /* Check for changes in accounts */ { unsigned int len = json_array_size (payto_uris); - bool matches[GNUNET_NZL (len)]; + struct TMH_WireMethod *matches[GNUNET_NZL (len)]; bool matched; memset (matches, @@ -205,6 +205,7 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, { const char *uri = json_string_value (json_object_get (wm->j_wire, "payto_uri")); + GNUNET_assert (NULL != uri); matched = false; for (unsigned int i = 0; irollback (TMH_db->cls); @@ -236,13 +237,14 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, TALER_EC_GENERIC_PAYTO_URI_MALFORMED, str); } - matches[i] = true; + matches[i] = wm; matched = true; break; } } /* delete unmatched (= removed) accounts */ - if (! matched) + if ( (! matched) && + (wm->active) ) { /* Account was REMOVED */ GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -267,8 +269,25 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh, struct TALER_MERCHANTDB_AccountDetails ad; struct TMH_WireMethod *wm; - if (matches[i]) - continue; /* account existed */ + if (NULL != matches[i]) + { + wm = matches[i]; + if (! wm->active) + { + qs = TMH_db->activate_account (TMH_db->cls, + &wm->h_wire); + if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs) + { + TMH_db->rollback (TMH_db->cls); + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + goto retry; + else + goto giveup; + } + } + wm->enabling = true; + continue; + } ad.payto_uri = json_string_value (json_array_get (payto_uris, i)); GNUNET_assert (NULL != ad.payto_uri); @@ -359,8 +378,11 @@ giveup: /* We did not flip the 'active' bits earlier because the DB transaction could still fail. Now it is time to update our runtime state. */ + GNUNET_assert (! (wm->deleting & wm->enabling)); if (wm->deleting) wm->active = false; + if (wm->enabling) + wm->active = true; } /* Update our 'settings' */ diff --git a/src/backend/taler-merchant-httpd_private-post-orders.c b/src/backend/taler-merchant-httpd_private-post-orders.c index 7162945c..e2103ecc 100644 --- a/src/backend/taler-merchant-httpd_private-post-orders.c +++ b/src/backend/taler-merchant-httpd_private-post-orders.c @@ -973,7 +973,7 @@ add_payment_details (struct MHD_Connection *connection, if (NULL != payment_target) { while ( (NULL != wm) && - (GNUNET_YES == wm->active) && + (wm->active) && (0 != strcasecmp (payment_target, wm->wire_method) ) ) wm = wm->next; diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c index 4506c57e..616172f1 100644 --- a/src/backenddb/plugin_merchantdb_postgres.c +++ b/src/backenddb/plugin_merchantdb_postgres.c @@ -660,8 +660,7 @@ static enum GNUNET_DB_QueryStatus postgres_insert_account ( void *cls, const char *id, - const struct - TALER_MERCHANTDB_AccountDetails *account_details) + const struct TALER_MERCHANTDB_AccountDetails *account_details) { struct PostgresClosure *pg = cls; uint8_t active = account_details->active; @@ -790,6 +789,30 @@ postgres_inactivate_account (void *cls, } +/** + * Set an instance's account in our database to "active". + * + * @param cls closure + * @param h_wire hash of the wire account to set to active + * @return database result code + */ +static enum GNUNET_DB_QueryStatus +postgres_activate_account (void *cls, + const struct GNUNET_HashCode *h_wire) +{ + struct PostgresClosure *pg = cls; + struct GNUNET_PQ_QueryParam params[] = { + GNUNET_PQ_query_param_auto_from_type (h_wire), + GNUNET_PQ_query_param_end + }; + + check_connection (pg); + return GNUNET_PQ_eval_prepared_non_select (pg->conn, + "activate_account", + params); +} + + /** * Context used for postgres_lookup_products(). */ @@ -6136,6 +6159,12 @@ postgres_connect (void *cls) " active=FALSE" " WHERE h_wire = $1", 1), + /* for postgres_activate_account() */ + GNUNET_PQ_make_prepare ("activate_account", + "UPDATE merchant_accounts SET" + " active=TRUE" + " WHERE h_wire = $1", + 1), /* for postgres_lookup_products() */ GNUNET_PQ_make_prepare ("lookup_products", "SELECT" @@ -8458,6 +8487,7 @@ libtaler_plugin_merchantdb_postgres_init (void *cls) plugin->delete_instance_private_key = &postgres_delete_instance_private_key; plugin->purge_instance = &postgres_purge_instance; plugin->update_instance = &postgres_update_instance; + plugin->activate_account = &postgres_activate_account; plugin->inactivate_account = &postgres_inactivate_account; plugin->lookup_products = &postgres_lookup_products; plugin->lookup_product = &postgres_lookup_product; diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h index 7d7bd9dc..963f9234 100644 --- a/src/include/taler_merchantdb_plugin.h +++ b/src/include/taler_merchantdb_plugin.h @@ -846,6 +846,18 @@ struct TALER_MERCHANTDB_Plugin (*inactivate_account)(void *cls, const struct GNUNET_HashCode *h_wire); + + /** + * Set an instance's account in our database to "active". + * + * @param cls closure + * @param h_wire hash of the wire account to set to active + * @return database result code + */ + enum GNUNET_DB_QueryStatus + (*activate_account)(void *cls, + const struct GNUNET_HashCode *h_wire); + /** * Lookup all of the products the given instance has configured. * -- cgit v1.2.3