anastasis-gtk_handle-identity-changed.c (5855B)
1 /* 2 This file is part of anastasis-gtk. 3 Copyright (C) 2020 Anastasis SARL 4 5 Anastasis is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published 7 by the Free Software Foundation; either version 3, or (at your 8 option) any later version. 9 10 Anastasis 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 License 16 along with Anastasis; see the file COPYING. If not, write to the 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 Boston, MA 02110-1301, USA. 19 */ 20 /** 21 * @file src/anastasis/anastasis-gtk_handle-identity-changed.c 22 * @brief 23 * @author Christian Grothoff 24 * @author Dennis Neufeld 25 */ 26 #include <gnunet/gnunet_util_lib.h> 27 #include "anastasis-gtk_helper.h" 28 #include "anastasis-gtk_action.h" 29 #include "anastasis-gtk_attributes.h" 30 #include "anastasis-gtk_handle-identity-changed.h" 31 #include <jansson.h> 32 33 34 /** 35 * CSS class our style sheet paints in the "invalid input" colour. 36 */ 37 #define INVALID_CSS_CLASS "anastasis-invalid" 38 39 40 /** 41 * Enable or disable highlighting of widget @a w as problematic. 42 * 43 * @param w widget to highlight, NULL is tolerated 44 * @param on true to enable highlighting, false to disable 45 */ 46 static void 47 highlight (GtkWidget *w, 48 bool on) 49 { 50 if (NULL == w) 51 return; 52 if (on) 53 gtk_widget_add_css_class (w, 54 INVALID_CSS_CLASS); 55 else 56 gtk_widget_remove_css_class (w, 57 INVALID_CSS_CLASS); 58 } 59 60 61 void 62 AG_mark_invalid_input (const char *name) 63 { 64 const json_t *id_attributes; 65 size_t index; 66 json_t *id_attr; 67 68 id_attributes = json_object_get (AG_redux_state, 69 "required_attributes"); 70 json_array_foreach (id_attributes, index, id_attr) 71 { 72 const char *widget_name = NULL; 73 const char *attr_type; 74 const char *attr_uuid; 75 const char *attr_name; 76 struct GNUNET_JSON_Specification spec[] = { 77 GNUNET_JSON_spec_mark_optional ( 78 GNUNET_JSON_spec_string ("widget", 79 &widget_name), 80 NULL), 81 GNUNET_JSON_spec_string ("type", 82 &attr_type), 83 GNUNET_JSON_spec_string ("uuid", 84 &attr_uuid), 85 GNUNET_JSON_spec_string ("name", 86 &attr_name), 87 GNUNET_JSON_spec_end () 88 }; 89 GtkWidget *w = NULL; 90 91 GNUNET_assert (GNUNET_OK == 92 GNUNET_JSON_parse (id_attr, 93 spec, 94 NULL, NULL)); 95 if (NULL != widget_name) 96 { 97 char *data_name; 98 99 data_name = AG_expand_name (widget_name, 100 attr_type); 101 w = GTK_WIDGET (GCG_get_main_window_object (data_name)); 102 GNUNET_free (data_name); 103 } 104 if (NULL == w) 105 { 106 struct GNUNET_HashCode uh; 107 108 GNUNET_CRYPTO_hash (attr_uuid, 109 strlen (attr_uuid), 110 &uh); 111 w = GNUNET_CONTAINER_multihashmap_get (AG_entry_attributes, 112 &uh); 113 } 114 highlight (w, 115 (0 == strcmp (name, 116 attr_name))); 117 GNUNET_JSON_parse_free (spec); 118 } 119 } 120 121 122 /** 123 * Function called with the results of #ANASTASIS_redux_action. 124 * 125 * @param cls closure 126 * @param error_code Error code 127 * @param response new state as result or config information of provider 128 */ 129 static void 130 test_ok_cb (void *cls, 131 enum TALER_ErrorCode error_code, 132 json_t *response) 133 { 134 bool *result = cls; 135 const char *name; 136 137 switch (error_code) 138 { 139 case TALER_EC_NONE: 140 *result = true; 141 AG_mark_invalid_input ("__none__"); 142 break; 143 case TALER_EC_GENERIC_PARAMETER_MISSING: 144 /* should not be possible */ 145 GNUNET_break (0); 146 break; 147 case TALER_EC_ANASTASIS_REDUCER_STATE_INVALID: 148 /* should not be possible */ 149 GNUNET_break (0); 150 break; 151 case TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID: 152 /* should not be possible */ 153 GNUNET_break (0); 154 break; 155 case TALER_EC_ANASTASIS_REDUCER_INPUT_REGEX_FAILED: 156 name = json_string_value (json_object_get (response, 157 "detail")); 158 AG_mark_invalid_input (name); 159 break; 160 case TALER_EC_ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED: 161 name = json_string_value (json_object_get (response, 162 "detail")); 163 AG_mark_invalid_input (name); 164 break; 165 default: 166 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 167 "Unexpected error code %d from reducer\n", 168 error_code); 169 break; 170 } 171 } 172 173 174 /** 175 * Function to ckeck if required attributes are set. 176 * 177 * @return true if user-provided attributes satisfy the constraints 178 */ 179 static bool 180 check_attributes_fullfilled (void) 181 { 182 struct ANASTASIS_ReduxAction *ta; 183 json_t *args; 184 bool result; 185 186 args = AG_collect_attributes (false); 187 if (NULL == args) 188 return false; 189 result = false; 190 ta = ANASTASIS_redux_action (AG_redux_state, 191 "enter_user_attributes", 192 args, 193 &test_ok_cb, 194 &result); 195 if (NULL != ta) 196 { 197 result = true; 198 AG_mark_invalid_input ("__none__"); 199 ANASTASIS_redux_action_cancel (ta); 200 } 201 json_decref (args); 202 return result; 203 } 204 205 206 void 207 AG_identity_changed (void) 208 { 209 if (check_attributes_fullfilled ()) 210 AG_enable_next (); 211 else 212 AG_insensitive ("anastasis_gtk_main_window_forward_button"); 213 }