Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2023, 2024 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Affero General Public License as
7 : published by the Free Software Foundation; either version 3,
8 : or (at your option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU General Public License for more details.
14 :
15 : You should have received a copy of the GNU General Public
16 : License along with TALER; see the file COPYING. If not,
17 : see <http://www.gnu.org/licenses/>
18 : */
19 :
20 : /**
21 : * @file taler-merchant-httpd_private-patch-token-families-SLUG.c
22 : * @brief implementing PATCH /tokenfamilies/$SLUG request handling
23 : * @author Christian Blättler
24 : */
25 : #include "platform.h"
26 : #include "taler-merchant-httpd_private-patch-token-families-SLUG.h"
27 : #include "taler-merchant-httpd_helper.h"
28 : #include <taler/taler_json_lib.h>
29 :
30 :
31 : /**
32 : * How often do we retry the simple INSERT database transaction?
33 : */
34 : #define MAX_RETRIES 3
35 :
36 :
37 : /**
38 : * Handle a PATCH "/tokenfamilies/$slug" request.
39 : *
40 : * @param rh context of the handler
41 : * @param connection the MHD connection to handle
42 : * @param[in,out] hc context with further information about the request
43 : * @return MHD result code
44 : */
45 : MHD_RESULT
46 0 : TMH_private_patch_token_family_SLUG (const struct TMH_RequestHandler *rh,
47 : struct MHD_Connection *connection,
48 : struct TMH_HandlerContext *hc)
49 : {
50 0 : struct TMH_MerchantInstance *mi = hc->instance;
51 0 : const char *slug = hc->infix;
52 0 : struct TALER_MERCHANTDB_TokenFamilyDetails details = {0};
53 : struct GNUNET_JSON_Specification spec[] = {
54 0 : GNUNET_JSON_spec_string ("name",
55 : (const char **) &details.name),
56 0 : GNUNET_JSON_spec_string ("description",
57 : (const char **) &details.description),
58 0 : GNUNET_JSON_spec_mark_optional (
59 : GNUNET_JSON_spec_json ("description_i18n",
60 : &details.description_i18n),
61 : NULL),
62 0 : GNUNET_JSON_spec_mark_optional (
63 : GNUNET_JSON_spec_json ("extra_data",
64 : &details.extra_data),
65 : NULL),
66 0 : GNUNET_JSON_spec_timestamp ("valid_after",
67 : &details.valid_after),
68 0 : GNUNET_JSON_spec_timestamp ("valid_before",
69 : &details.valid_before),
70 0 : GNUNET_JSON_spec_end ()
71 : };
72 :
73 0 : GNUNET_assert (NULL != mi);
74 0 : GNUNET_assert (NULL != slug);
75 : {
76 : enum GNUNET_GenericReturnValue res;
77 :
78 0 : res = TALER_MHD_parse_json_data (connection,
79 0 : hc->request_body,
80 : spec);
81 0 : if (GNUNET_OK != res)
82 : return (GNUNET_NO == res)
83 : ? MHD_YES
84 0 : : MHD_NO;
85 : }
86 :
87 : /* Ensure that valid_after is before valid_before */
88 0 : if (GNUNET_TIME_timestamp_cmp (details.valid_after,
89 : >=,
90 : details.valid_before))
91 : {
92 0 : GNUNET_break_op (0);
93 0 : GNUNET_JSON_parse_free (spec);
94 0 : return TALER_MHD_reply_with_error (connection,
95 : MHD_HTTP_BAD_REQUEST,
96 : TALER_EC_GENERIC_PARAMETER_MALFORMED,
97 : "valid_after >= valid_before");
98 : }
99 :
100 0 : if (NULL == details.description_i18n)
101 : {
102 0 : details.description_i18n = json_object ();
103 0 : GNUNET_assert (NULL != details.description_i18n);
104 : }
105 0 : if (! TALER_JSON_check_i18n (details.description_i18n))
106 : {
107 0 : GNUNET_break_op (0);
108 0 : GNUNET_JSON_parse_free (spec);
109 0 : return TALER_MHD_reply_with_error (connection,
110 : MHD_HTTP_BAD_REQUEST,
111 : TALER_EC_GENERIC_PARAMETER_MALFORMED,
112 : "description_i18n");
113 : }
114 :
115 : {
116 : enum GNUNET_DB_QueryStatus qs;
117 0 : MHD_RESULT ret = MHD_NO;
118 :
119 0 : qs = TMH_db->update_token_family (TMH_db->cls,
120 0 : mi->settings.id,
121 : slug,
122 : &details);
123 0 : switch (qs)
124 : {
125 0 : case GNUNET_DB_STATUS_HARD_ERROR:
126 0 : GNUNET_break (0);
127 0 : ret = TALER_MHD_reply_with_error (connection,
128 : MHD_HTTP_INTERNAL_SERVER_ERROR,
129 : TALER_EC_GENERIC_DB_STORE_FAILED,
130 : NULL);
131 0 : break;
132 0 : case GNUNET_DB_STATUS_SOFT_ERROR:
133 0 : GNUNET_break (0);
134 0 : ret = TALER_MHD_reply_with_error (connection,
135 : MHD_HTTP_INTERNAL_SERVER_ERROR,
136 : TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
137 : "unexpected serialization problem");
138 0 : break;
139 0 : case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
140 0 : ret = TALER_MHD_reply_with_error (connection,
141 : MHD_HTTP_NOT_FOUND,
142 : TALER_EC_MERCHANT_PATCH_TOKEN_FAMILY_NOT_FOUND,
143 : slug);
144 0 : break;
145 0 : case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
146 0 : ret = TALER_MHD_reply_static (connection,
147 : MHD_HTTP_NO_CONTENT,
148 : NULL,
149 : NULL,
150 : 0);
151 0 : break;
152 : }
153 0 : GNUNET_JSON_parse_free (spec);
154 0 : return ret;
155 : }
156 : }
157 :
158 :
159 : /* end of taler-merchant-httpd_private-patch-token-families-SLUG.c */
|