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