Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2020-2023 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see
15 : <http://www.gnu.org/licenses/>
16 : */
17 : /**
18 : * @file lib/exchange_api_management_drain_profits.c
19 : * @brief functions to set wire fees at an exchange
20 : * @author Christian Grothoff
21 : */
22 : #include "platform.h"
23 : #include "taler_json_lib.h"
24 : #include <gnunet/gnunet_curl_lib.h>
25 : #include <microhttpd.h>
26 : #include "exchange_api_curl_defaults.h"
27 : #include "taler_exchange_service.h"
28 : #include "taler_signatures.h"
29 : #include "taler_curl_lib.h"
30 : #include "taler_json_lib.h"
31 :
32 :
33 : struct TALER_EXCHANGE_ManagementDrainProfitsHandle
34 : {
35 :
36 : /**
37 : * The url for this request.
38 : */
39 : char *url;
40 :
41 : /**
42 : * Minor context that holds body and headers.
43 : */
44 : struct TALER_CURL_PostContext post_ctx;
45 :
46 : /**
47 : * Handle for the request.
48 : */
49 : struct GNUNET_CURL_Job *job;
50 :
51 : /**
52 : * Function to call with the result.
53 : */
54 : TALER_EXCHANGE_ManagementDrainProfitsCallback cb;
55 :
56 : /**
57 : * Closure for @a cb.
58 : */
59 : void *cb_cls;
60 :
61 : /**
62 : * Reference to the execution context.
63 : */
64 : struct GNUNET_CURL_Context *ctx;
65 : };
66 :
67 :
68 : /**
69 : * Function called when we're done processing the
70 : * HTTP /management/drain request.
71 : *
72 : * @param cls the `struct TALER_EXCHANGE_ManagementDrainProfitsHandle *`
73 : * @param response_code HTTP response code, 0 on error
74 : * @param response response body, NULL if not in JSON
75 : */
76 : static void
77 1 : handle_drain_profits_finished (void *cls,
78 : long response_code,
79 : const void *response)
80 : {
81 1 : struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp = cls;
82 1 : const json_t *json = response;
83 1 : struct TALER_EXCHANGE_ManagementDrainResponse dr = {
84 1 : .hr.http_status = (unsigned int) response_code,
85 : .hr.reply = json
86 : };
87 :
88 1 : dp->job = NULL;
89 1 : switch (response_code)
90 : {
91 1 : case MHD_HTTP_NO_CONTENT:
92 1 : break;
93 0 : case MHD_HTTP_FORBIDDEN:
94 0 : dr.hr.ec = TALER_JSON_get_error_code (json);
95 0 : dr.hr.hint = TALER_JSON_get_error_hint (json);
96 0 : break;
97 0 : case MHD_HTTP_CONFLICT:
98 0 : dr.hr.ec = TALER_JSON_get_error_code (json);
99 0 : dr.hr.hint = TALER_JSON_get_error_hint (json);
100 0 : break;
101 0 : case MHD_HTTP_PRECONDITION_FAILED:
102 0 : dr.hr.ec = TALER_JSON_get_error_code (json);
103 0 : dr.hr.hint = TALER_JSON_get_error_hint (json);
104 0 : break;
105 0 : default:
106 : /* unexpected response code */
107 0 : GNUNET_break_op (0);
108 0 : dr.hr.ec = TALER_JSON_get_error_code (json);
109 0 : dr.hr.hint = TALER_JSON_get_error_hint (json);
110 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
111 : "Unexpected response code %u/%d for exchange management drain profits\n",
112 : (unsigned int) response_code,
113 : (int) dr.hr.ec);
114 0 : break;
115 : }
116 1 : if (NULL != dp->cb)
117 : {
118 1 : dp->cb (dp->cb_cls,
119 : &dr);
120 1 : dp->cb = NULL;
121 : }
122 1 : TALER_EXCHANGE_management_drain_profits_cancel (dp);
123 1 : }
124 :
125 :
126 : struct TALER_EXCHANGE_ManagementDrainProfitsHandle *
127 1 : TALER_EXCHANGE_management_drain_profits (
128 : struct GNUNET_CURL_Context *ctx,
129 : const char *url,
130 : const struct TALER_WireTransferIdentifierRawP *wtid,
131 : const struct TALER_Amount *amount,
132 : struct GNUNET_TIME_Timestamp date,
133 : const char *account_section,
134 : const struct TALER_FullPayto payto_uri,
135 : const struct TALER_MasterSignatureP *master_sig,
136 : TALER_EXCHANGE_ManagementDrainProfitsCallback cb,
137 : void *cb_cls)
138 : {
139 : struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp;
140 : CURL *eh;
141 : json_t *body;
142 :
143 1 : dp = GNUNET_new (struct TALER_EXCHANGE_ManagementDrainProfitsHandle);
144 1 : dp->cb = cb;
145 1 : dp->cb_cls = cb_cls;
146 1 : dp->ctx = ctx;
147 1 : dp->url = TALER_url_join (url,
148 : "management/drain",
149 : NULL);
150 1 : if (NULL == dp->url)
151 : {
152 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
153 : "Could not construct request URL.\n");
154 0 : GNUNET_free (dp);
155 0 : return NULL;
156 : }
157 1 : body = GNUNET_JSON_PACK (
158 : GNUNET_JSON_pack_string ("debit_account_section",
159 : account_section),
160 : TALER_JSON_pack_full_payto ("credit_payto_uri",
161 : payto_uri),
162 : GNUNET_JSON_pack_data_auto ("wtid",
163 : wtid),
164 : GNUNET_JSON_pack_data_auto ("master_sig",
165 : master_sig),
166 : GNUNET_JSON_pack_timestamp ("date",
167 : date),
168 : TALER_JSON_pack_amount ("amount",
169 : amount));
170 1 : eh = TALER_EXCHANGE_curl_easy_get_ (dp->url);
171 2 : if ( (NULL == eh) ||
172 : (GNUNET_OK !=
173 1 : TALER_curl_easy_post (&dp->post_ctx,
174 : eh,
175 : body)) )
176 : {
177 0 : GNUNET_break (0);
178 0 : if (NULL != eh)
179 0 : curl_easy_cleanup (eh);
180 0 : json_decref (body);
181 0 : GNUNET_free (dp->url);
182 0 : return NULL;
183 : }
184 1 : json_decref (body);
185 1 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
186 : "Requesting URL '%s'\n",
187 : dp->url);
188 2 : dp->job = GNUNET_CURL_job_add2 (ctx,
189 : eh,
190 1 : dp->post_ctx.headers,
191 : &handle_drain_profits_finished,
192 : dp);
193 1 : if (NULL == dp->job)
194 : {
195 0 : TALER_EXCHANGE_management_drain_profits_cancel (dp);
196 0 : return NULL;
197 : }
198 1 : return dp;
199 : }
200 :
201 :
202 : void
203 1 : TALER_EXCHANGE_management_drain_profits_cancel (
204 : struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp)
205 : {
206 1 : if (NULL != dp->job)
207 : {
208 0 : GNUNET_CURL_job_cancel (dp->job);
209 0 : dp->job = NULL;
210 : }
211 1 : TALER_curl_easy_post_finished (&dp->post_ctx);
212 1 : GNUNET_free (dp->url);
213 1 : GNUNET_free (dp);
214 1 : }
|