challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit 7ad0be8ea7e217ef1a713f471661d8c8dee1df75
parent 2eacd7f53c8e5eddb20eaf30ab968cf37ebda388
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 22 Nov 2024 14:34:41 +0100

allow passing address already to /setup

Diffstat:
Msrc/challenger/challenger-httpd_config.c | 3++-
Msrc/challenger/challenger-httpd_setup.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/challengerdb/pg_setup_nonce.c | 9+++++++--
Msrc/challengerdb/pg_setup_nonce.h | 5++++-
Msrc/include/challenger_database_plugin.h | 5++++-
5 files changed, 91 insertions(+), 7 deletions(-)

diff --git a/src/challenger/challenger-httpd_config.c b/src/challenger/challenger-httpd_config.c @@ -30,6 +30,7 @@ * 1: revision to support SPA * 2: add support to restrict addresses by REGEX and a few other SPA enhancements * 3: added support for RFC7636 + * 4: added support to pre-initialize address during /setup. */ @@ -75,7 +76,7 @@ CH_handler_config (struct CH_HandlerContext *hc, GNUNET_JSON_pack_object_incref ("restrictions", CH_restrictions), GNUNET_JSON_pack_string ("version", - "3:0:1")); + "4:0:2")); GNUNET_break (MHD_YES == MHD_add_response_header (response, MHD_HTTP_HEADER_EXPIRES, diff --git a/src/challenger/challenger-httpd_setup.c b/src/challenger/challenger-httpd_setup.c @@ -1,6 +1,6 @@ /* This file is part of Challenger - Copyright (C) 2023 Taler Systems SA + Copyright (C) 2023, 2024 Taler Systems SA Challenger 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 @@ -24,15 +24,86 @@ #include "challenger-httpd_setup.h" #include "challenger-httpd_common.h" +struct SetupContext +{ + + /** + * Our handler context. + */ + struct CH_HandlerContext *hc; + + /** + * Opaque parsing context. + */ + void *opaque_post_parsing_context; + + /** + * Uploaded JSON data, NULL if upload is not yet complete. + */ + json_t *root; + +}; + + +/** + * Callback to clean up the request context. + * + * @param[in,out] ctx a `struct SetupContext` to clean up + */ +static void +request_done (void *ctx) +{ + struct SetupContext *sc = ctx; + + if (NULL != sc->root) + { + json_decref (sc->root); + sc->root = NULL; + } + TALER_MHD_parse_post_cleanup_callback (sc->opaque_post_parsing_context); + GNUNET_free (sc); +} + MHD_RESULT CH_handler_setup (struct CH_HandlerContext *hc, const char *upload_data, size_t *upload_data_size) { + struct SetupContext *sc = hc->ctx; unsigned long long client_id; const char *client_secret; + if (NULL == sc) + { + /* Fresh request, do initial setup */ + sc = GNUNET_new (struct SetupContext); + sc->hc = hc; + hc->cc = &request_done; + } + if ( (NULL == sc->root) && + (0 != *upload_data_size) ) + { + /* parse byte stream upload into JSON */ + enum GNUNET_GenericReturnValue res; + + res = TALER_MHD_parse_post_json (hc->connection, + &sc->opaque_post_parsing_context, + upload_data, + upload_data_size, + &sc->root); + if (GNUNET_SYSERR == res) + { + GNUNET_assert (NULL == sc->root); + return MHD_NO; /* bad upload, could not even generate error */ + } + if ( (GNUNET_NO == res) || + (NULL == sc->root) ) + { + GNUNET_assert (NULL == sc->root); + return MHD_YES; /* so far incomplete upload or parser error */ + } + } (void) upload_data; (void) upload_data_size; { @@ -101,7 +172,8 @@ CH_handler_setup (struct CH_HandlerContext *hc, qs = CH_db->setup_nonce (CH_db->cls, client_id, &nonce, - expiration_time); + expiration_time, + NULL); switch (qs) { case GNUNET_DB_STATUS_HARD_ERROR: diff --git a/src/challengerdb/pg_setup_nonce.c b/src/challengerdb/pg_setup_nonce.c @@ -30,13 +30,17 @@ enum GNUNET_DB_QueryStatus CH_PG_setup_nonce (void *cls, uint64_t client_id, const struct CHALLENGER_ValidationNonceP *nonce, - struct GNUNET_TIME_Absolute expiration_time) + struct GNUNET_TIME_Absolute expiration_time, + const json_t *initial_address) { struct PostgresClosure *pg = cls; struct GNUNET_PQ_QueryParam params[] = { GNUNET_PQ_query_param_uint64 (&client_id), GNUNET_PQ_query_param_auto_from_type (nonce), GNUNET_PQ_query_param_absolute_time (&expiration_time), + NULL == initial_address + ? GNUNET_PQ_query_param_null () + : TALER_PQ_query_param_json (initial_address), GNUNET_PQ_query_param_end }; @@ -47,7 +51,8 @@ CH_PG_setup_nonce (void *cls, " ,nonce" " ,expiration_time" " ,client_redirect_uri" - ") SELECT $1, $2, $3, uri" + " ,address" + ") SELECT $1, $2, $3, uri, $4" " FROM CLIENTS" " WHERE client_serial_id=$1;"); return GNUNET_PQ_eval_prepared_non_select (pg->conn, diff --git a/src/challengerdb/pg_setup_nonce.h b/src/challengerdb/pg_setup_nonce.h @@ -34,12 +34,15 @@ * @param client_id ID of the client * @param nonce unique nonce to use to identify the validation * @param expiration_time when will the validation expire + * @param initial_address address the user should validate, + * NULL if the user should enter it themselves * @return transaction status */ enum GNUNET_DB_QueryStatus CH_PG_setup_nonce (void *cls, uint64_t client_id, const struct CHALLENGER_ValidationNonceP *nonce, - struct GNUNET_TIME_Absolute expiration_time); + struct GNUNET_TIME_Absolute expiration_time, + const json_t *initial_address); #endif diff --git a/src/include/challenger_database_plugin.h b/src/include/challenger_database_plugin.h @@ -224,13 +224,16 @@ struct CHALLENGER_DatabasePlugin * @param client_id ID of the client * @param nonce unique nonce to use to identify the validation * @param expiration_time when will the validation expire + * @param initial_address address the user should validate, + * NULL if the user should enter it themselves * @return transaction status */ enum GNUNET_DB_QueryStatus (*setup_nonce)(void *cls, uint64_t client_id, const struct CHALLENGER_ValidationNonceP *nonce, - struct GNUNET_TIME_Absolute expiration_time); + struct GNUNET_TIME_Absolute expiration_time, + const json_t *initial_address); /**