testing_api_cmd_set_officer.c (8393B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it 6 under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3, or (at your 8 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 GNU 13 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, see 17 <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file testing/testing_api_cmd_set_officer.c 21 * @brief command for testing /management/aml-officers 22 * @author Christian Grothoff 23 */ 24 #include "taler/platform.h" 25 26 struct SetOfficerState; 27 #define TALER_EXCHANGE_POST_MANAGEMENT_AML_OFFICERS_RESULT_CLOSURE \ 28 struct SetOfficerState 29 #include "taler/taler-exchange/post-management-aml-officers.h" 30 31 #include "taler/taler_json_lib.h" 32 #include <gnunet/gnunet_curl_lib.h> 33 #include "taler/taler_testing_lib.h" 34 #include "taler/taler_signatures.h" 35 #include "taler/backoff.h" 36 37 38 /** 39 * State for a "set_officer" CMD. 40 */ 41 struct SetOfficerState 42 { 43 44 /** 45 * Update AML officer handle while operation is running. 46 */ 47 struct TALER_EXCHANGE_PostManagementAmlOfficersHandle *dh; 48 49 /** 50 * Our interpreter. 51 */ 52 struct TALER_TESTING_Interpreter *is; 53 54 /** 55 * Reference to command to previous set officer 56 * to update, or NULL. 57 */ 58 const char *ref_cmd; 59 60 /** 61 * Name to use for the officer. 62 */ 63 const char *name; 64 65 /** 66 * Private key of the AML officer. 67 */ 68 struct TALER_AmlOfficerPrivateKeyP officer_priv; 69 70 /** 71 * Public key of the AML officer. 72 */ 73 struct TALER_AmlOfficerPublicKeyP officer_pub; 74 75 /** 76 * Is the officer supposed to be enabled? 77 */ 78 bool is_active; 79 80 /** 81 * Is access supposed to be read-only? 82 */ 83 bool read_only; 84 85 }; 86 87 88 /** 89 * Callback to analyze the /management/XXX response, just used to check 90 * if the response code is acceptable. 91 * 92 * @param ds our context 93 * @param ar response details 94 */ 95 static void 96 set_officer_cb ( 97 struct SetOfficerState *ds, 98 const struct TALER_EXCHANGE_PostManagementAmlOfficersResponse *ar) 99 { 100 const struct TALER_EXCHANGE_HttpResponse *hr = &ar->hr; 101 102 ds->dh = NULL; 103 if (MHD_HTTP_NO_CONTENT != hr->http_status) 104 { 105 TALER_TESTING_unexpected_status (ds->is, 106 hr->http_status, 107 MHD_HTTP_NO_CONTENT); 108 return; 109 } 110 TALER_TESTING_interpreter_next (ds->is); 111 } 112 113 114 /** 115 * Run the command. 116 * 117 * @param cls closure. 118 * @param cmd the command to execute. 119 * @param is the interpreter state. 120 */ 121 static void 122 set_officer_run (void *cls, 123 const struct TALER_TESTING_Command *cmd, 124 struct TALER_TESTING_Interpreter *is) 125 { 126 struct SetOfficerState *ds = cls; 127 struct GNUNET_TIME_Timestamp now; 128 struct TALER_MasterSignatureP master_sig; 129 const char *exchange_url; 130 131 (void) cmd; 132 { 133 const struct TALER_TESTING_Command *exchange_cmd; 134 135 exchange_cmd = TALER_TESTING_interpreter_get_command (is, 136 "exchange"); 137 if (NULL == exchange_cmd) 138 { 139 GNUNET_break (0); 140 TALER_TESTING_interpreter_fail (is); 141 return; 142 } 143 GNUNET_assert (GNUNET_OK == 144 TALER_TESTING_get_trait_exchange_url (exchange_cmd, 145 &exchange_url)); 146 } 147 now = GNUNET_TIME_timestamp_get (); 148 ds->is = is; 149 if (NULL == ds->ref_cmd) 150 { 151 GNUNET_CRYPTO_eddsa_key_create (&ds->officer_priv.eddsa_priv); 152 GNUNET_CRYPTO_eddsa_key_get_public (&ds->officer_priv.eddsa_priv, 153 &ds->officer_pub.eddsa_pub); 154 } 155 else 156 { 157 const struct TALER_TESTING_Command *ref; 158 const struct TALER_AmlOfficerPrivateKeyP *officer_priv; 159 const struct TALER_AmlOfficerPublicKeyP *officer_pub; 160 161 ref = TALER_TESTING_interpreter_lookup_command (is, 162 ds->ref_cmd); 163 if (NULL == ref) 164 { 165 GNUNET_break (0); 166 TALER_TESTING_interpreter_fail (is); 167 return; 168 } 169 GNUNET_assert (GNUNET_OK == 170 TALER_TESTING_get_trait_officer_pub (ref, 171 &officer_pub)); 172 GNUNET_assert (GNUNET_OK == 173 TALER_TESTING_get_trait_officer_priv (ref, 174 &officer_priv)); 175 ds->officer_pub = *officer_pub; 176 ds->officer_priv = *officer_priv; 177 } 178 { 179 const struct TALER_TESTING_Command *exchange_cmd; 180 const struct TALER_MasterPrivateKeyP *master_priv; 181 182 exchange_cmd = TALER_TESTING_interpreter_get_command (is, 183 "exchange"); 184 if (NULL == exchange_cmd) 185 { 186 GNUNET_break (0); 187 TALER_TESTING_interpreter_fail (is); 188 return; 189 } 190 GNUNET_assert (GNUNET_OK == 191 TALER_TESTING_get_trait_master_priv (exchange_cmd, 192 &master_priv)); 193 194 TALER_exchange_offline_aml_officer_status_sign (&ds->officer_pub, 195 ds->name, 196 now, 197 ds->is_active, 198 ds->read_only, 199 master_priv, 200 &master_sig); 201 } 202 ds->dh = TALER_EXCHANGE_post_management_aml_officers_create ( 203 TALER_TESTING_interpreter_get_context (is), 204 exchange_url, 205 &ds->officer_pub, 206 ds->name, 207 now, 208 ds->is_active, 209 ds->read_only, 210 &master_sig); 211 if (NULL == ds->dh) 212 { 213 GNUNET_break (0); 214 TALER_TESTING_interpreter_fail (is); 215 return; 216 } 217 GNUNET_assert (TALER_EC_NONE == 218 TALER_EXCHANGE_post_management_aml_officers_start ( 219 ds->dh, 220 &set_officer_cb, 221 ds)); 222 } 223 224 225 /** 226 * Free the state of a "set_officer" CMD, and possibly cancel a 227 * pending operation thereof. 228 * 229 * @param cls closure, must be a `struct SetOfficerState`. 230 * @param cmd the command which is being cleaned up. 231 */ 232 static void 233 set_officer_cleanup (void *cls, 234 const struct TALER_TESTING_Command *cmd) 235 { 236 struct SetOfficerState *ds = cls; 237 238 if (NULL != ds->dh) 239 { 240 TALER_TESTING_command_incomplete (ds->is, 241 cmd->label); 242 TALER_EXCHANGE_post_management_aml_officers_cancel (ds->dh); 243 ds->dh = NULL; 244 } 245 GNUNET_free (ds); 246 } 247 248 249 /** 250 * Offer internal data of a "set officer" CMD state to other 251 * commands. 252 * 253 * @param cls closure 254 * @param[out] ret result (could be anything) 255 * @param trait name of the trait 256 * @param index index number of the object to offer. 257 * @return #GNUNET_OK on success 258 */ 259 static enum GNUNET_GenericReturnValue 260 set_officer_traits (void *cls, 261 const void **ret, 262 const char *trait, 263 unsigned int index) 264 { 265 struct SetOfficerState *ws = cls; 266 struct TALER_TESTING_Trait traits[] = { 267 TALER_TESTING_make_trait_officer_pub (&ws->officer_pub), 268 TALER_TESTING_make_trait_officer_priv (&ws->officer_priv), 269 TALER_TESTING_make_trait_officer_name (ws->name), 270 TALER_TESTING_trait_end () 271 }; 272 273 return TALER_TESTING_get_trait (traits, 274 ret, 275 trait, 276 index); 277 } 278 279 280 struct TALER_TESTING_Command 281 TALER_TESTING_cmd_set_officer ( 282 const char *label, 283 const char *ref_cmd, 284 const char *name, 285 bool is_active, 286 bool read_only) 287 { 288 struct SetOfficerState *ds; 289 290 ds = GNUNET_new (struct SetOfficerState); 291 ds->ref_cmd = ref_cmd; 292 ds->name = name; 293 ds->is_active = is_active; 294 ds->read_only = read_only; 295 { 296 struct TALER_TESTING_Command cmd = { 297 .cls = ds, 298 .label = label, 299 .run = &set_officer_run, 300 .cleanup = &set_officer_cleanup, 301 .traits = &set_officer_traits 302 }; 303 304 return cmd; 305 } 306 } 307 308 309 /* end of testing_api_cmd_set_officer.c */