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 src/backend/taler-merchant-httpd_patch-private-tokenfamilies-TOKEN_FAMILY_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_patch-private-tokenfamilies-TOKEN_FAMILY_SLUG.h"
27 : #include "taler-merchant-httpd_helper.h"
28 : #include <taler/taler_json_lib.h>
29 : #include "merchant-database/update_token_family.h"
30 :
31 :
32 : /**
33 : * How often do we retry the simple INSERT database transaction?
34 : */
35 : #define MAX_RETRIES 3
36 :
37 :
38 : /**
39 : * Handle a PATCH "/tokenfamilies/$slug" request.
40 : *
41 : * @param rh context of the handler
42 : * @param connection the MHD connection to handle
43 : * @param[in,out] hc context with further information about the request
44 : * @return MHD result code
45 : */
46 : enum MHD_Result
47 0 : TMH_private_patch_token_family_SLUG (const struct TMH_RequestHandler *rh,
48 : struct MHD_Connection *connection,
49 : struct TMH_HandlerContext *hc)
50 : {
51 0 : struct TMH_MerchantInstance *mi = hc->instance;
52 0 : const char *slug = hc->infix;
53 0 : struct TALER_MERCHANTDB_TokenFamilyDetails details = {
54 : .valid_before = GNUNET_TIME_UNIT_FOREVER_TS
55 : };
56 : struct GNUNET_JSON_Specification spec[] = {
57 0 : GNUNET_JSON_spec_string ("name",
58 : (const char **) &details.name),
59 0 : GNUNET_JSON_spec_string ("description",
60 : (const char **) &details.description),
61 0 : GNUNET_JSON_spec_mark_optional (
62 : GNUNET_JSON_spec_json ("description_i18n",
63 : &details.description_i18n),
64 : NULL),
65 0 : GNUNET_JSON_spec_mark_optional (
66 : GNUNET_JSON_spec_json ("extra_data",
67 : &details.extra_data),
68 : NULL),
69 0 : GNUNET_JSON_spec_timestamp ("valid_after",
70 : &details.valid_after),
71 0 : GNUNET_JSON_spec_mark_optional (
72 : GNUNET_JSON_spec_timestamp ("valid_before",
73 : &details.valid_before),
74 : NULL),
75 0 : GNUNET_JSON_spec_end ()
76 : };
77 :
78 0 : GNUNET_assert (NULL != mi);
79 0 : GNUNET_assert (NULL != slug);
80 : {
81 : enum GNUNET_GenericReturnValue res;
82 :
83 0 : res = TALER_MHD_parse_json_data (connection,
84 0 : hc->request_body,
85 : spec);
86 0 : if (GNUNET_OK != res)
87 : return (GNUNET_NO == res)
88 : ? MHD_YES
89 0 : : MHD_NO;
90 : }
91 :
92 : /* Ensure that valid_after is before valid_before */
93 0 : if (GNUNET_TIME_timestamp_cmp (details.valid_after,
94 : >=,
95 : details.valid_before))
96 : {
97 0 : GNUNET_break_op (0);
98 0 : GNUNET_JSON_parse_free (spec);
99 0 : return TALER_MHD_reply_with_error (connection,
100 : MHD_HTTP_BAD_REQUEST,
101 : TALER_EC_GENERIC_PARAMETER_MALFORMED,
102 : "valid_after >= valid_before");
103 : }
104 :
105 0 : if (NULL == details.description_i18n)
106 : {
107 0 : details.description_i18n = json_object ();
108 0 : GNUNET_assert (NULL != details.description_i18n);
109 : }
110 0 : if (! TALER_JSON_check_i18n (details.description_i18n))
111 : {
112 0 : GNUNET_break_op (0);
113 0 : GNUNET_JSON_parse_free (spec);
114 0 : return TALER_MHD_reply_with_error (connection,
115 : MHD_HTTP_BAD_REQUEST,
116 : TALER_EC_GENERIC_PARAMETER_MALFORMED,
117 : "description_i18n");
118 : }
119 :
120 : {
121 : enum GNUNET_DB_QueryStatus qs;
122 0 : enum MHD_Result ret = MHD_NO;
123 :
124 0 : qs = TALER_MERCHANTDB_update_token_family (TMH_db,
125 0 : mi->settings.id,
126 : slug,
127 : &details);
128 0 : switch (qs)
129 : {
130 0 : case GNUNET_DB_STATUS_HARD_ERROR:
131 0 : GNUNET_break (0);
132 0 : ret = TALER_MHD_reply_with_error (connection,
133 : MHD_HTTP_INTERNAL_SERVER_ERROR,
134 : TALER_EC_GENERIC_DB_STORE_FAILED,
135 : NULL);
136 0 : break;
137 0 : case GNUNET_DB_STATUS_SOFT_ERROR:
138 0 : GNUNET_break (0);
139 0 : ret = TALER_MHD_reply_with_error (connection,
140 : MHD_HTTP_INTERNAL_SERVER_ERROR,
141 : TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE,
142 : "unexpected serialization problem");
143 0 : break;
144 0 : case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
145 0 : ret = TALER_MHD_reply_with_error (connection,
146 : MHD_HTTP_NOT_FOUND,
147 : TALER_EC_MERCHANT_PATCH_TOKEN_FAMILY_NOT_FOUND,
148 : slug);
149 0 : break;
150 0 : case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
151 0 : ret = TALER_MHD_reply_static (connection,
152 : MHD_HTTP_NO_CONTENT,
153 : NULL,
154 : NULL,
155 : 0);
156 0 : break;
157 : }
158 0 : GNUNET_JSON_parse_free (spec);
159 0 : return ret;
160 : }
161 : }
162 :
163 :
164 : /* end of taler-merchant-httpd_patch-private-tokenfamilies-TOKEN_FAMILY_SLUG.c */
|