summaryrefslogtreecommitdiff
path: root/src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2021-03-01 23:25:21 +0100
committerFlorian Dold <florian@dold.me>2021-03-01 23:25:21 +0100
commite29a6603fd830338742d295b426728cfd7c9c4af (patch)
treeca60f138b4a7a9e2765571c197b165ce41e0e009 /src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c
parentc18d676333c148a3c9fb5eea75089c1cff599c21 (diff)
downloadmerchant-e29a6603fd830338742d295b426728cfd7c9c4af.tar.gz
merchant-e29a6603fd830338742d295b426728cfd7c9c4af.tar.bz2
merchant-e29a6603fd830338742d295b426728cfd7c9c4af.zip
towards updated auth API (tests still missing)
Diffstat (limited to 'src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c')
-rw-r--r--src/backend/taler-merchant-httpd_private-post-instances-ID-auth.c162
1 files changed, 162 insertions, 0 deletions
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 */