anastasis-gtk_handle-identity-changed.c (6389B)
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 * Enable or disable highlighting of widget @a w as problematic. 36 * 37 * @param on true to enable highlighting, false to disable 38 */ 39 static void 40 highlight (GtkWidget *w, 41 bool on) 42 { 43 static GtkCssProvider *gcp; 44 GtkStyleContext *gsc; 45 46 if (NULL == gcp) 47 { 48 GError *err = NULL; 49 50 gcp = gtk_css_provider_new (); 51 GNUNET_break (true == 52 gtk_css_provider_load_from_data (gcp, 53 "* {background-color: #FF4500;}", 54 -1, 55 &err)); 56 if (NULL != err) 57 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 58 "Failed to parse CSS: %s\n", 59 err->message); 60 } 61 gsc = gtk_widget_get_style_context (w); 62 if (on) 63 { 64 gtk_style_context_add_provider (gsc, 65 GTK_STYLE_PROVIDER (gcp), 66 GTK_STYLE_PROVIDER_PRIORITY_USER); 67 } 68 else 69 { 70 gtk_style_context_remove_provider (gsc, 71 GTK_STYLE_PROVIDER (gcp)); 72 } 73 } 74 75 76 void 77 AG_mark_invalid_input (const char *name) 78 { 79 const json_t *id_attributes; 80 size_t index; 81 json_t *id_attr; 82 83 id_attributes = json_object_get (AG_redux_state, 84 "required_attributes"); 85 json_array_foreach (id_attributes, index, id_attr) 86 { 87 const char *widget_name = NULL; 88 const char *attr_type; 89 const char *attr_uuid; 90 const char *attr_name; 91 struct GNUNET_JSON_Specification spec[] = { 92 GNUNET_JSON_spec_mark_optional ( 93 GNUNET_JSON_spec_string ("widget", 94 &widget_name), 95 NULL), 96 GNUNET_JSON_spec_string ("type", 97 &attr_type), 98 GNUNET_JSON_spec_string ("uuid", 99 &attr_uuid), 100 GNUNET_JSON_spec_string ("name", 101 &attr_name), 102 GNUNET_JSON_spec_end () 103 }; 104 GtkWidget *w = NULL; 105 106 GNUNET_assert (GNUNET_OK == 107 GNUNET_JSON_parse (id_attr, 108 spec, 109 NULL, NULL)); 110 if (NULL != widget_name) 111 { 112 char *data_name; 113 114 data_name = AG_expand_name (widget_name, 115 attr_type); 116 w = GTK_WIDGET (GCG_get_main_window_object (data_name)); 117 GNUNET_free (data_name); 118 } 119 if (NULL == w) 120 { 121 struct GNUNET_HashCode uh; 122 123 GNUNET_CRYPTO_hash (attr_uuid, 124 strlen (attr_uuid), 125 &uh); 126 w = GNUNET_CONTAINER_multihashmap_get (AG_entry_attributes, 127 &uh); 128 } 129 highlight (w, 130 (0 == strcmp (name, 131 attr_name))); 132 GNUNET_JSON_parse_free (spec); 133 } 134 } 135 136 137 /** 138 * Function called with the results of #ANASTASIS_redux_action. 139 * 140 * @param cls closure 141 * @param error_code Error code 142 * @param response new state as result or config information of provider 143 */ 144 static void 145 test_ok_cb (void *cls, 146 enum TALER_ErrorCode error_code, 147 json_t *response) 148 { 149 bool *result = cls; 150 const char *name; 151 152 switch (error_code) 153 { 154 case TALER_EC_NONE: 155 *result = true; 156 AG_mark_invalid_input ("__none__"); 157 break; 158 case TALER_EC_GENERIC_PARAMETER_MISSING: 159 /* should not be possible */ 160 GNUNET_break (0); 161 break; 162 case TALER_EC_ANASTASIS_REDUCER_STATE_INVALID: 163 /* should not be possible */ 164 GNUNET_break (0); 165 break; 166 case TALER_EC_ANASTASIS_REDUCER_INPUT_INVALID: 167 /* should not be possible */ 168 GNUNET_break (0); 169 break; 170 case TALER_EC_ANASTASIS_REDUCER_INPUT_REGEX_FAILED: 171 name = json_string_value (json_object_get (response, 172 "detail")); 173 AG_mark_invalid_input (name); 174 break; 175 case TALER_EC_ANASTASIS_REDUCER_INPUT_VALIDATION_FAILED: 176 name = json_string_value (json_object_get (response, 177 "detail")); 178 AG_mark_invalid_input (name); 179 break; 180 default: 181 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 182 "Unexpected error code %d from reducer\n", 183 error_code); 184 break; 185 } 186 } 187 188 189 /** 190 * Function to ckeck if required attributes are set. 191 * 192 * @return true if user-provided attributes satisfy the constraints 193 */ 194 static bool 195 check_attributes_fullfilled (void) 196 { 197 struct ANASTASIS_ReduxAction *ta; 198 json_t *args; 199 bool result; 200 201 args = AG_collect_attributes (false); 202 if (NULL == args) 203 return false; 204 result = false; 205 ta = ANASTASIS_redux_action (AG_redux_state, 206 "enter_user_attributes", 207 args, 208 &test_ok_cb, 209 &result); 210 if (NULL != ta) 211 { 212 result = true; 213 AG_mark_invalid_input ("__none__"); 214 ANASTASIS_redux_action_cancel (ta); 215 } 216 json_decref (args); 217 return result; 218 } 219 220 221 void 222 AG_identity_changed (void) 223 { 224 if (check_attributes_fullfilled ()) 225 AG_enable_next (); 226 else 227 AG_insensitive ("anastasis_gtk_main_window_forward_button"); 228 }