summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--src/backend/Makefile.am2
-rw-r--r--src/backend/taler-merchant-httpd.c23
-rw-r--r--src/backend/taler-merchant-httpd.h5
-rw-r--r--src/backend/taler-merchant-httpd_private-patch-instances-ID.c27
-rw-r--r--src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c162
-rw-r--r--src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h44
-rw-r--r--src/backend/taler-merchant-httpd_private-post-instances.c69
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c64
-rw-r--r--src/backenddb/test_merchantdb.c6
-rw-r--r--src/include/taler_merchantdb_plugin.h45
-rw-r--r--src/lib/merchant_api_post_instances.c27
-rw-r--r--src/testing/test_merchant_api.c5
13 files changed, 403 insertions, 77 deletions
diff --git a/.gitignore b/.gitignore
index f40449cf..90301629 100644
--- a/.gitignore
+++ b/.gitignore
@@ -80,3 +80,4 @@ doc/stamp-?
doc/stamp-vti
doc/mdate-sh
doc/texinfo.tex
+.private-key
diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am
index 4c05db42..3dd126a6 100644
--- a/src/backend/Makefile.am
+++ b/src/backend/Makefile.am
@@ -66,6 +66,8 @@ taler_merchant_httpd_SOURCES = \
taler-merchant-httpd_private-patch-products-ID.h \
taler-merchant-httpd_private-post-instances.c \
taler-merchant-httpd_private-post-instances.h \
+ taler-merchant-httpd_private-post-instances-ID-auth.c \
+ taler-merchant-httpd_private-post-instances-ID-auth.h \
taler-merchant-httpd_private-post-products.c \
taler-merchant-httpd_private-post-products.h \
taler-merchant-httpd_private-post-products-ID-lock.c \
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c
index 7f9f8e3b..0690e621 100644
--- a/src/backend/taler-merchant-httpd.c
+++ b/src/backend/taler-merchant-httpd.c
@@ -49,6 +49,7 @@
#include "taler-merchant-httpd_private-patch-orders-ID-forget.h"
#include "taler-merchant-httpd_private-patch-products-ID.h"
#include "taler-merchant-httpd_private-post-instances.h"
+#include "taler-merchant-httpd_private-post-instances-ID-auth.h"
#include "taler-merchant-httpd_private-post-orders.h"
#include "taler-merchant-httpd_private-post-orders-ID-refund.h"
#include "taler-merchant-httpd_private-post-products.h"
@@ -1053,6 +1054,14 @@ url_handler (void *cls,
in the code... */
.max_upload = 1024 * 1024 * 8
},
+ /* POST /auth: */
+ {
+ .url_prefix = "/auth",
+ .method = MHD_HTTP_METHOD_POST,
+ .handler = &TMH_private_post_instances_ID_auth,
+ /* Body should be pretty small. */
+ .max_upload = 1024 * 1024,
+ },
/* GET /products: */
{
.url_prefix = "/products",
@@ -1494,8 +1503,8 @@ url_handler (void *cls,
{
/* Override default instance access control */
TMH_compute_auth (default_auth,
- &hc->instance->settings.auth_salt,
- &hc->instance->settings.auth_hash);
+ &hc->instance->auth.auth_salt,
+ &hc->instance->auth.auth_hash);
GNUNET_free (default_auth);
}
}
@@ -1677,8 +1686,8 @@ url_handler (void *cls,
(NULL == default_auth) )
auth_ok = (GNUNET_OK ==
TMH_check_auth (auth,
- &def_instance->settings.auth_salt,
- &def_instance->settings.auth_hash));
+ &def_instance->auth.auth_salt,
+ &def_instance->auth.auth_hash));
/* Only permit 'default' auth if we are either working with
the default instance OR patching/deleting an instance OR have no instance */
if ( (hc->rh->handler != &TMH_private_patch_instances_ID) &&
@@ -1691,8 +1700,8 @@ url_handler (void *cls,
if (NULL != hc->instance)
auth_ok |= (GNUNET_OK ==
TMH_check_auth (auth,
- &hc->instance->settings.auth_salt,
- &hc->instance->settings.auth_hash));
+ &hc->instance->auth.auth_salt,
+ &hc->instance->auth.auth_hash));
if (! auth_ok)
{
if (auth_malformed)
@@ -1777,6 +1786,7 @@ add_instance_cb (void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
const struct TALER_MERCHANTDB_InstanceSettings *is,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias,
unsigned int accounts_length,
const struct TALER_MERCHANTDB_AccountDetails accounts[])
{
@@ -1786,6 +1796,7 @@ add_instance_cb (void *cls,
GNUNET_assert (NULL != merchant_priv);
mi = GNUNET_new (struct TMH_MerchantInstance);
mi->settings = *is;
+ mi->auth = *ias;
mi->settings.id = GNUNET_strdup (mi->settings.id);
mi->settings.name = GNUNET_strdup (mi->settings.name);
mi->settings.address = json_incref (mi->settings.address);
diff --git a/src/backend/taler-merchant-httpd.h b/src/backend/taler-merchant-httpd.h
index 50badbb1..7cb3c836 100644
--- a/src/backend/taler-merchant-httpd.h
+++ b/src/backend/taler-merchant-httpd.h
@@ -133,6 +133,11 @@ struct TMH_MerchantInstance
struct TALER_MERCHANTDB_InstanceSettings settings;
/**
+ * General settings for an instance.
+ */
+ struct TALER_MERCHANTDB_InstanceAuthSettings auth;
+
+ /**
* Reference counter on this structure. Only destroyed if the
* counter hits zero.
*/
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 637ded04..edda6228 100644
--- a/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
+++ b/src/backend/taler-merchant-httpd_private-patch-instances-ID.c
@@ -63,14 +63,10 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh,
struct TMH_MerchantInstance *mi = hc->instance;
struct TALER_MERCHANTDB_InstanceSettings is;
json_t *payto_uris;
- const char *auth_token = NULL;
const char *name;
struct TMH_WireMethod *wm_head = NULL;
struct TMH_WireMethod *wm_tail = NULL;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("auth_token",
- &auth_token)),
GNUNET_JSON_spec_json ("payto_uris",
&payto_uris),
GNUNET_JSON_spec_string ("name",
@@ -149,14 +145,6 @@ TMH_private_patch_instances_ID (const struct TMH_RequestHandler *rh,
/* Check for equality of settings */
if (! ( (0 == strcmp (mi->settings.name,
name)) &&
- ( ( (NULL != auth_token) &&
- (GNUNET_OK ==
- TMH_check_auth (auth_token,
- &mi->settings.auth_salt,
- &mi->settings.auth_hash)) ) ||
- ( (NULL == auth_token) &&
- (GNUNET_YES ==
- GNUNET_is_zero (&mi->settings.auth_hash))) ) &&
(1 == json_equal (mi->settings.address,
is.address)) &&
(1 == json_equal (mi->settings.jurisdiction,
@@ -404,21 +392,6 @@ giveup:
json_decref (mi->settings.address);
json_decref (mi->settings.jurisdiction);
is.id = mi->settings.id;
- if (NULL == auth_token)
- {
- memset (&is.auth_salt,
- 0,
- sizeof (is.auth_salt));
- memset (&is.auth_hash,
- 0,
- sizeof (is.auth_hash));
- }
- else
- {
- TMH_compute_auth (auth_token,
- &is.auth_salt,
- &is.auth_hash);
- }
mi->settings = is;
mi->settings.address = json_incref (mi->settings.address);
mi->settings.jurisdiction = json_incref (mi->settings.jurisdiction);
diff --git a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c
new file mode 100644
index 00000000..8d8df93f
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c
@@ -0,0 +1,162 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems SA
+
+ GNU Taler is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation; either version 3,
+ or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not,
+ see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file taler-merchant-httpd_private-post-instances-ID-auth.c
+ * @brief implementing POST /instances/$ID/auth request handling
+ * @author Christian Grothoff
+ * @author Florian Dold
+ */
+#include "platform.h"
+#include "taler-merchant-httpd_private-post-instances-ID-auth.h"
+#include <taler/taler_json_lib.h>
+
+
+/**
+ * How often do we retry the simple INSERT database transaction?
+ */
+#define MAX_RETRIES 3
+
+
+/**
+ * Change the authentication settings of an instance.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] hc context with further information about the request
+ * @return MHD result code
+ */
+MHD_RESULT
+TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc)
+{
+ struct TALER_MERCHANTDB_InstanceAuthSettings ias;
+ const char *auth_token = NULL;
+ struct TMH_MerchantInstance *mi = hc->instance;
+ json_t *jauth = hc->request_body;
+
+ {
+ bool auth_ok = false;
+ const char *auth_method = json_string_value (json_object_get (jauth,
+ "method"));
+
+ if (NULL == auth_method)
+ GNUNET_break_op (0);
+ else if (0 == strcmp (auth_method, "external"))
+ {
+ auth_token = NULL;
+ auth_ok = true;
+ }
+ else if (0 == strcmp (auth_method, "token"))
+ {
+ auth_token = json_string_value (json_object_get (jauth, "token"));
+ if (NULL != auth_token)
+ {
+ if (0 != strncasecmp (RFC_8959_PREFIX,
+ auth_token,
+ strlen (RFC_8959_PREFIX)))
+ GNUNET_break_op (0);
+ else
+ auth_ok = true;
+ }
+ else
+ GNUNET_break_op (0);
+ }
+
+ if (! auth_ok)
+ {
+ GNUNET_break_op (0);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_MERCHANT_PRIVATE_POST_INSTANCE_AUTH_BAD_AUTH,
+ "bad authentication config");
+ }
+ }
+
+ if (NULL == auth_token)
+ {
+ memset (&ias.auth_salt,
+ 0,
+ sizeof (ias.auth_salt));
+ memset (&ias.auth_hash,
+ 0,
+ sizeof (ias.auth_hash));
+ }
+ else
+ {
+ TMH_compute_auth (auth_token,
+ &ias.auth_salt,
+ &ias.auth_hash);
+ }
+
+ {
+ enum GNUNET_DB_QueryStatus qs;
+
+ for (unsigned int i = 0; i<MAX_RETRIES; i++)
+ {
+ if (GNUNET_OK !=
+ TMH_db->start (TMH_db->cls,
+ "post /instances/$ID/auth"))
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_START_FAILED,
+ NULL);
+ }
+ qs = TMH_db->update_instance_auth (TMH_db->cls,
+ mi->settings.id,
+ &ias);
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ TMH_db->rollback (TMH_db->cls);
+ goto retry;
+ }
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+ {
+ GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ TMH_db->rollback (TMH_db->cls);
+ goto retry;
+ }
+ qs = TMH_db->commit (TMH_db->cls);
+ if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
+ qs = GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
+retry:
+ if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+ break; /* success! -- or hard failure */
+ } /* for .. MAX_RETRIES */
+ if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
+ {
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_INTERNAL_SERVER_ERROR,
+ TALER_EC_GENERIC_DB_COMMIT_FAILED,
+ NULL);
+ }
+ /* Finally, also update our running process */
+ mi->auth = ias;
+ }
+ return TALER_MHD_reply_static (connection,
+ MHD_HTTP_NO_CONTENT,
+ NULL,
+ NULL,
+ 0);
+}
+
+/* end of taler-merchant-httpd_private-post-instances-ID-auth.c */
diff --git a/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h
new file mode 100644
index 00000000..3a47c42c
--- /dev/null
+++ b/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.h
@@ -0,0 +1,44 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems SA
+
+ GNU Taler is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation; either version 3,
+ or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public
+ License along with TALER; see the file COPYING. If not,
+ see <http://www.gnu.org/licenses/>
+*/
+
+/**
+ * @file taler-merchant-httpd_private-post-instances-ID-auth.h
+ * @brief implements POST /instances/$ID/auth request handling
+ * @author Christian Grothoff
+ * @author Florian Dold
+ */
+#ifndef TALER_MERCHANT_HTTPD_PRIVATE_POST_INSTANCES_ID_AUTH_H
+#define TALER_MERCHANT_HTTPD_PRIVATE_POST_INSTANCES_ID_AUTH_H
+#include "taler-merchant-httpd.h"
+
+
+/**
+ * Change the instance's auth settings.
+ *
+ * @param rh context of the handler
+ * @param connection the MHD connection to handle
+ * @param[in,out] hc context with further information about the request
+ * @return MHD result code
+ */
+MHD_RESULT
+TMH_private_post_instances_ID_auth (const struct TMH_RequestHandler *rh,
+ struct MHD_Connection *connection,
+ struct TMH_HandlerContext *hc);
+
+#endif
diff --git a/src/backend/taler-merchant-httpd_private-post-instances.c b/src/backend/taler-merchant-httpd_private-post-instances.c
index c4d1d617..88a51a26 100644
--- a/src/backend/taler-merchant-httpd_private-post-instances.c
+++ b/src/backend/taler-merchant-httpd_private-post-instances.c
@@ -141,14 +141,15 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
struct TMH_HandlerContext *hc)
{
struct TALER_MERCHANTDB_InstanceSettings is;
+ struct TALER_MERCHANTDB_InstanceAuthSettings ias;
json_t *payto_uris;
const char *auth_token = NULL;
struct TMH_WireMethod *wm_head = NULL;
struct TMH_WireMethod *wm_tail = NULL;
+ json_t *jauth;
struct GNUNET_JSON_Specification spec[] = {
- GNUNET_JSON_spec_mark_optional (
- GNUNET_JSON_spec_string ("auth_token",
- &auth_token)),
+ GNUNET_JSON_spec_json ("auth",
+ &jauth),
GNUNET_JSON_spec_json ("payto_uris",
&payto_uris),
GNUNET_JSON_spec_string ("id",
@@ -184,6 +185,47 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
: MHD_NO;
}
+
+ {
+ bool auth_ok = false;
+ const char *auth_method = json_string_value (json_object_get (jauth,
+ "method"));
+
+ if (NULL == auth_method)
+ GNUNET_break_op (0);
+ else if (0 == strcmp (auth_method, "external"))
+ {
+ auth_token = NULL;
+ auth_ok = true;
+ }
+ else if (0 == strcmp (auth_method, "token"))
+ {
+ auth_token = json_string_value (json_object_get (jauth, "token"));
+ if (NULL != auth_token)
+ {
+ if (0 != strncasecmp (RFC_8959_PREFIX,
+ auth_token,
+ strlen (RFC_8959_PREFIX)))
+ GNUNET_break_op (0);
+ else
+ auth_ok = true;
+ }
+ else
+ GNUNET_break_op (0);
+ }
+
+ if (! auth_ok)
+ {
+ GNUNET_break_op (0);
+ GNUNET_JSON_parse_free (spec);
+ return TALER_MHD_reply_with_error (connection,
+ MHD_HTTP_BAD_REQUEST,
+ TALER_EC_MERCHANT_PRIVATE_POST_INSTANCES_BAD_AUTH,
+ "bad authentication config");
+ }
+ }
+
+
if ((0 != strcasecmp (is.default_max_deposit_fee.currency,
TMH_currency)) ||
(0 != strcasecmp (is.default_max_wire_fee.currency,
@@ -212,11 +254,11 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
( ( (NULL != auth_token) &&
(GNUNET_OK ==
TMH_check_auth (auth_token,
- &mi->settings.auth_salt,
- &mi->settings.auth_hash)) ) ||
+ &mi->auth.auth_salt,
+ &mi->auth.auth_hash)) ) ||
( (NULL == auth_token) &&
(GNUNET_YES ==
- GNUNET_is_zero (&mi->settings.auth_hash))) ) &&
+ GNUNET_is_zero (&mi->auth.auth_hash))) ) &&
(1 == json_equal (mi->settings.address,
is.address)) &&
(1 == json_equal (mi->settings.jurisdiction,
@@ -357,18 +399,18 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
if (NULL == auth_token)
{
- memset (&is.auth_salt,
+ memset (&ias.auth_salt,
0,
- sizeof (is.auth_salt));
- memset (&is.auth_hash,
+ sizeof (ias.auth_salt));
+ memset (&ias.auth_hash,
0,
- sizeof (is.auth_hash));
+ sizeof (ias.auth_hash));
}
else
{
TMH_compute_auth (auth_token,
- &is.auth_salt,
- &is.auth_hash);
+ &ias.auth_salt,
+ &ias.auth_hash);
}
{
struct TMH_MerchantInstance *mi;
@@ -402,7 +444,8 @@ TMH_private_post_instances (const struct TMH_RequestHandler *rh,
qs = TMH_db->insert_instance (TMH_db->cls,
&mi->merchant_pub,
&mi->merchant_priv,
- &mi->settings);
+ &mi->settings,
+ &mi->auth);
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT != qs)
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index 616172f1..a1b659db 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -343,6 +343,11 @@ struct LookupInstancesContext
struct TALER_MERCHANTDB_InstanceSettings is;
/**
+ * Instance authentication settings, valid only during find_instances_cb().
+ */
+ struct TALER_MERCHANTDB_InstanceAuthSettings ias;
+
+ /**
* Instance serial number, valid only during find_instances_cb().
*/
uint64_t instance_serial;
@@ -407,6 +412,7 @@ call_with_accounts (struct LookupInstancesContext *lic,
&lic->merchant_pub,
(0 == qs) ? NULL : &merchant_priv,
&lic->is,
+ &lic->ias,
num_accounts,
accounts);
}
@@ -493,11 +499,11 @@ lookup_instances_cb (void *cls,
&lic->merchant_pub),
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("auth_hash",
- &lic->is.auth_hash),
+ &lic->ias.auth_hash),
&no_auth),
GNUNET_PQ_result_spec_allow_null (
GNUNET_PQ_result_spec_auto_from_type ("auth_salt",
- &lic->is.auth_salt),
+ &lic->ias.auth_salt),
&no_salt),
GNUNET_PQ_result_spec_string ("merchant_id",
&lic->is.id),
@@ -524,12 +530,12 @@ lookup_instances_cb (void *cls,
GNUNET_PQ_query_param_end
};
- memset (&lic->is.auth_salt,
+ memset (&lic->ias.auth_salt,
0,
- sizeof (lic->is.auth_salt));
- memset (&lic->is.auth_hash,
+ sizeof (lic->ias.auth_salt));
+ memset (&lic->ias.auth_hash,
0,
- sizeof (lic->is.auth_hash));
+ sizeof (lic->ias.auth_hash));
if (GNUNET_OK !=
GNUNET_PQ_extract_result (result,
rs,
@@ -610,13 +616,14 @@ static enum GNUNET_DB_QueryStatus
postgres_insert_instance (void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
- const struct TALER_MERCHANTDB_InstanceSettings *is)
+ const struct TALER_MERCHANTDB_InstanceSettings *is,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias)
{
struct PostgresClosure *pg = cls;
struct GNUNET_PQ_QueryParam params[] = {
GNUNET_PQ_query_param_auto_from_type (merchant_pub),
- GNUNET_PQ_query_param_auto_from_type (&is->auth_hash),
- GNUNET_PQ_query_param_auto_from_type (&is->auth_salt),
+ GNUNET_PQ_query_param_auto_from_type (&ias->auth_hash),
+ GNUNET_PQ_query_param_auto_from_type (&ias->auth_salt),
GNUNET_PQ_query_param_string (is->id),
GNUNET_PQ_query_param_string (is->name),
TALER_PQ_query_param_json (is->address),
@@ -753,6 +760,31 @@ postgres_update_instance (void *cls,
GNUNET_PQ_query_param_relative_time (
&is->default_wire_transfer_delay),
GNUNET_PQ_query_param_relative_time (&is->default_pay_delay),
+ GNUNET_PQ_query_param_end
+ };
+
+ check_connection (pg);
+ return GNUNET_PQ_eval_prepared_non_select (pg->conn,
+ "update_instance",
+ params);
+}
+
+/**
+ * Update information about an instance's authentication settings
+ * into our database.
+ *
+ * @param cls closure
+ * @param ias details about the instance
+ * @return database result code
+ */
+static enum GNUNET_DB_QueryStatus
+postgres_update_instance_auth (void *cls,
+ const char *merchant_id,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *is)
+{
+ struct PostgresClosure *pg = cls;
+ struct GNUNET_PQ_QueryParam params[] = {
+ GNUNET_PQ_query_param_string (merchant_id),
GNUNET_PQ_query_param_auto_from_type (&is->auth_hash),
GNUNET_PQ_query_param_auto_from_type (&is->auth_salt),
GNUNET_PQ_query_param_end
@@ -760,7 +792,7 @@ postgres_update_instance (void *cls,
check_connection (pg);
return GNUNET_PQ_eval_prepared_non_select (pg->conn,
- "update_instance",
+ "update_instance_auth",
params);
}
@@ -6149,10 +6181,15 @@ postgres_connect (void *cls)
",default_wire_fee_amortization=$9"
",default_wire_transfer_delay=$10"
",default_pay_delay=$11"
- ",auth_hash=$12"
- ",auth_salt=$13"
" WHERE merchant_id = $1",
- 13),
+ 11),
+ /* for postgres_update_instance_auth() */
+ GNUNET_PQ_make_prepare ("update_instance_auth",
+ "UPDATE merchant_instances SET"
+ " auth_hash=$2"
+ ",auth_salt=$3"
+ " WHERE merchant_id = $1",
+ 3),
/* for postgres_inactivate_account() */
GNUNET_PQ_make_prepare ("inactivate_account",
"UPDATE merchant_accounts SET"
@@ -8487,6 +8524,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->update_instance_auth = &postgres_update_instance_auth;
plugin->activate_account = &postgres_activate_account;
plugin->inactivate_account = &postgres_inactivate_account;
plugin->lookup_products = &postgres_lookup_products;
diff --git a/src/backenddb/test_merchantdb.c b/src/backenddb/test_merchantdb.c
index 9be7933d..be07c3cf 100644
--- a/src/backenddb/test_merchantdb.c
+++ b/src/backenddb/test_merchantdb.c
@@ -266,6 +266,7 @@ check_accounts_equal (const struct TALER_MERCHANTDB_AccountDetails *a,
* @param merchant_pub public key of the instance
* @param merchant_priv private key of the instance, NULL if not available
* @param is general instance settings
+ * @param ias instance authentication settings
* @param accounts_length length of the @a accounts array
* @param accounts list of accounts of the merchant
*/
@@ -274,6 +275,7 @@ lookup_instances_cb (void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
const struct TALER_MERCHANTDB_InstanceSettings *is,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias,
unsigned int accounts_length,
const struct TALER_MERCHANTDB_AccountDetails accounts[])
{
@@ -324,11 +326,13 @@ static int
test_insert_instance (const struct InstanceData *instance,
enum GNUNET_DB_QueryStatus expected_result)
{
+ struct TALER_MERCHANTDB_InstanceAuthSettings ias = { 0 };
TEST_COND_RET_ON_FAIL (expected_result ==
plugin->insert_instance (plugin->cls,
&instance->merchant_pub,
&instance->merchant_priv,
- &instance->instance),
+ &instance->instance,
+ &ias),
"Insert instance failed\n");
return 0;
}
diff --git a/src/include/taler_merchantdb_plugin.h b/src/include/taler_merchantdb_plugin.h
index 963f9234..6f94e514 100644
--- a/src/include/taler_merchantdb_plugin.h
+++ b/src/include/taler_merchantdb_plugin.h
@@ -60,6 +60,22 @@ struct TALER_MERCHANTDB_AccountDetails
};
+/**
+ * Authentication settings for an instance.
+ */
+struct TALER_MERCHANTDB_InstanceAuthSettings
+{
+ /**
+ * Hash used for authentication. All zero if authentication is off.
+ */
+ struct GNUNET_HashCode auth_hash;
+
+ /**
+ * Salt used to hash the "Authentication" header, the result must then
+ * match the @e auth_hash.
+ */
+ struct GNUNET_ShortHashCode auth_salt;
+};
/**
* General settings for an instance.
@@ -118,17 +134,6 @@ struct TALER_MERCHANTDB_InstanceSettings
*/
struct GNUNET_TIME_Relative default_pay_delay;
- /**
- * Hash used for authentication. All zero if authentication is off.
- */
- struct GNUNET_HashCode auth_hash;
-
- /**
- * Salt used to hash the "Authentication" header, the result must then
- * match the @e auth_hash.
- */
- struct GNUNET_ShortHashCode auth_salt;
-
};
@@ -148,6 +153,7 @@ typedef void
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
const struct TALER_MERCHANTDB_InstanceSettings *is,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias,
unsigned int accounts_length,
const struct TALER_MERCHANTDB_AccountDetails accounts[]);
@@ -784,7 +790,8 @@ struct TALER_MERCHANTDB_Plugin
(*insert_instance)(void *cls,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
- const struct TALER_MERCHANTDB_InstanceSettings *is);
+ const struct TALER_MERCHANTDB_InstanceSettings *is,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias);
/**
* Insert information about an instance's account into our database.
@@ -836,6 +843,20 @@ struct TALER_MERCHANTDB_Plugin
const struct TALER_MERCHANTDB_InstanceSettings *is);
/**
+ * Update information about an instance's authentication settings
+ * into our database.
+ *
+ * @param cls closure
+ * @param merchant_id merchant backend instance ID
+ * @param ias instance auth settings
+ * @return database result code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*update_instance_auth)(void *cls,
+ const char *merchant_id,
+ const struct TALER_MERCHANTDB_InstanceAuthSettings *ias);
+
+ /**
* Set an instance's account in our database to "inactive".
*
* @param cls closure
diff --git a/src/lib/merchant_api_post_instances.c b/src/lib/merchant_api_post_instances.c
index a6452045..8aede243 100644
--- a/src/lib/merchant_api_post_instances.c
+++ b/src/lib/merchant_api_post_instances.c
@@ -178,6 +178,7 @@ TALER_MERCHANT_instances_post (
struct TALER_MERCHANT_InstancesPostHandle *iph;
json_t *jpayto_uris;
json_t *req_obj;
+ json_t *auth_obj;
if (NULL != auth_token)
{
@@ -190,11 +191,27 @@ TALER_MERCHANT_instances_post (
RFC_8959_PREFIX);
return NULL;
}
- auth_token += strlen (RFC_8959_PREFIX);
+ auth_obj = json_pack ("{s:s, s:s}",
+ "method",
+ "token",
+ "token",
+ auth_token);
+ }
+ else
+ {
+ auth_obj = json_pack ("{s:s}",
+ "method",
+ "external");
+ }
+ if (NULL == auth_obj)
+ {
+ GNUNET_break (0);
+ return NULL;
}
jpayto_uris = json_array ();
if (NULL == jpayto_uris)
{
+ json_decref (auth_obj);
GNUNET_break (0);
return NULL;
}
@@ -205,13 +222,14 @@ TALER_MERCHANT_instances_post (
json_string (payto_uris[i])))
{
GNUNET_break (0);
+ json_decref (auth_obj);
json_decref (jpayto_uris);
return NULL;
}
}
req_obj = json_pack ("{s:o, s:s, s:s, s:O, s:O"
",s:o, s:I: s:o, s:o, s:o"
- ",s:s?}",
+ ",s:o}",
"payto_uris",
jpayto_uris,
"id",
@@ -233,10 +251,11 @@ TALER_MERCHANT_instances_post (
GNUNET_JSON_from_time_rel (default_wire_transfer_delay),
"default_pay_delay",
GNUNET_JSON_from_time_rel (default_pay_delay),
- "auth_token",
- auth_token);
+ "auth",
+ auth_obj);
if (NULL == req_obj)
{
+ json_decref (auth_obj);
GNUNET_break (0);
return NULL;
}
diff --git a/src/testing/test_merchant_api.c b/src/testing/test_merchant_api.c
index ea1e1258..93b6194f 100644
--- a/src/testing/test_merchant_api.c
+++ b/src/testing/test_merchant_api.c
@@ -1262,7 +1262,10 @@ run (void *cls,
"EUR:0.2",
GNUNET_TIME_UNIT_MINUTES,
GNUNET_TIME_UNIT_MINUTES,
- RFC_8959_PREFIX "EXAMPLE",
+ // FIXME: change this back once
+ // we have a update auth test CMD
+ //RFC_8959_PREFIX "EXAMPLE",
+ NULL,
MHD_HTTP_NO_CONTENT),
TALER_TESTING_cmd_merchant_patch_instance ("instance-patch-ACL",
merchant_url,