Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2022 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU Affero 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 Affero General Public License for more details.
12 :
13 : You should have received a copy of the GNU Affero General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file taler-exchange-httpd_management_drain.c
18 : * @brief Handle request to drain profits
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include <gnunet/gnunet_util_lib.h>
23 : #include <gnunet/gnunet_json_lib.h>
24 : #include <jansson.h>
25 : #include <microhttpd.h>
26 : #include <pthread.h>
27 : #include "taler_json_lib.h"
28 : #include "taler_mhd_lib.h"
29 : #include "taler_signatures.h"
30 : #include "taler-exchange-httpd_keys.h"
31 : #include "taler-exchange-httpd_management.h"
32 : #include "taler-exchange-httpd_responses.h"
33 :
34 :
35 : /**
36 : * Closure for the #drain transaction.
37 : */
38 : struct DrainContext
39 : {
40 : /**
41 : * Fee's signature affirming the #TALER_SIGNATURE_MASTER_DRAIN_PROFITS operation.
42 : */
43 : struct TALER_MasterSignatureP master_sig;
44 :
45 : /**
46 : * Wire transfer identifier to use.
47 : */
48 : struct TALER_WireTransferIdentifierRawP wtid;
49 :
50 : /**
51 : * Account to credit.
52 : */
53 : const char *payto_uri;
54 :
55 : /**
56 : * Configuration section with account to debit.
57 : */
58 : const char *account_section;
59 :
60 : /**
61 : * Signature time.
62 : */
63 : struct GNUNET_TIME_Timestamp date;
64 :
65 : /**
66 : * Amount to transfer.
67 : */
68 : struct TALER_Amount amount;
69 :
70 : };
71 :
72 :
73 : /**
74 : * Function implementing database transaction to drain profits. Runs the
75 : * transaction logic; IF it returns a non-error code, the transaction logic
76 : * MUST NOT queue a MHD response. IF it returns an hard error, the
77 : * transaction logic MUST queue a MHD response and set @a mhd_ret. IF it
78 : * returns the soft error code, the function MAY be called again to retry and
79 : * MUST not queue a MHD response.
80 : *
81 : * @param cls closure with a `struct DrainContext`
82 : * @param connection MHD request which triggered the transaction
83 : * @param[out] mhd_ret set to MHD response status for @a connection,
84 : * if transaction failed (!)
85 : * @return transaction status
86 : */
87 : static enum GNUNET_DB_QueryStatus
88 0 : drain (void *cls,
89 : struct MHD_Connection *connection,
90 : MHD_RESULT *mhd_ret)
91 : {
92 0 : struct DrainContext *dc = cls;
93 : enum GNUNET_DB_QueryStatus qs;
94 :
95 0 : qs = TEH_plugin->insert_drain_profit (
96 0 : TEH_plugin->cls,
97 0 : &dc->wtid,
98 : dc->account_section,
99 : dc->payto_uri,
100 : dc->date,
101 0 : &dc->amount,
102 0 : &dc->master_sig);
103 0 : if (qs < 0)
104 : {
105 0 : if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
106 0 : return qs;
107 0 : GNUNET_break (0);
108 0 : *mhd_ret = TALER_MHD_reply_with_error (connection,
109 : MHD_HTTP_INTERNAL_SERVER_ERROR,
110 : TALER_EC_GENERIC_DB_STORE_FAILED,
111 : "insert drain profit");
112 0 : return qs;
113 : }
114 0 : return qs;
115 : }
116 :
117 :
118 : MHD_RESULT
119 0 : TEH_handler_management_post_drain (
120 : struct MHD_Connection *connection,
121 : const json_t *root)
122 : {
123 : struct DrainContext dc;
124 : struct GNUNET_JSON_Specification spec[] = {
125 0 : GNUNET_JSON_spec_string ("debit_account_section",
126 : &dc.account_section),
127 0 : GNUNET_JSON_spec_string ("credit_payto_uri",
128 : &dc.payto_uri),
129 0 : GNUNET_JSON_spec_fixed_auto ("wtid",
130 : &dc.wtid),
131 0 : GNUNET_JSON_spec_fixed_auto ("master_sig",
132 : &dc.master_sig),
133 0 : GNUNET_JSON_spec_timestamp ("date",
134 : &dc.date),
135 0 : TALER_JSON_spec_amount ("amount",
136 : TEH_currency,
137 : &dc.amount),
138 0 : GNUNET_JSON_spec_end ()
139 : };
140 :
141 : {
142 : enum GNUNET_GenericReturnValue res;
143 :
144 0 : res = TALER_MHD_parse_json_data (connection,
145 : root,
146 : spec);
147 0 : if (GNUNET_SYSERR == res)
148 0 : return MHD_NO; /* hard failure */
149 0 : if (GNUNET_NO == res)
150 0 : return MHD_YES; /* failure */
151 : }
152 :
153 0 : TEH_METRICS_num_verifications[TEH_MT_SIGNATURE_EDDSA]++;
154 0 : if (GNUNET_OK !=
155 0 : TALER_exchange_offline_profit_drain_verify (
156 : &dc.wtid,
157 : dc.date,
158 : &dc.amount,
159 : dc.account_section,
160 : dc.payto_uri,
161 : &TEH_master_public_key,
162 : &dc.master_sig))
163 : {
164 : /* signature invalid */
165 0 : GNUNET_break_op (0);
166 0 : return TALER_MHD_reply_with_error (
167 : connection,
168 : MHD_HTTP_FORBIDDEN,
169 : TALER_EC_EXCHANGE_MANAGEMENT_DRAIN_PROFITS_SIGNATURE_INVALID,
170 : NULL);
171 : }
172 :
173 : {
174 : enum GNUNET_GenericReturnValue res;
175 : MHD_RESULT ret;
176 :
177 0 : res = TEH_DB_run_transaction (connection,
178 : "insert drain profit",
179 : TEH_MT_REQUEST_OTHER,
180 : &ret,
181 : &drain,
182 : &dc);
183 0 : if (GNUNET_SYSERR == res)
184 0 : return ret;
185 : }
186 0 : return TALER_MHD_reply_static (
187 : connection,
188 : MHD_HTTP_NO_CONTENT,
189 : NULL,
190 : NULL,
191 : 0);
192 : }
193 :
194 :
195 : /* end of taler-exchange-httpd_management_drain.c */
|