application/settings.c

changeset 65
48f43130b4a2
parent 64
98d0e2516f4e
child 66
eee1f3092844
equal deleted inserted replaced
64:98d0e2516f4e 65:48f43130b4a2
27 */ 27 */
28 28
29 #include "settings.h" 29 #include "settings.h"
30 30
31 #include <cx/list.h> 31 #include <cx/list.h>
32 #include <cx/array_list.h>
33 #include <cx/printf.h>
32 #include <libidav/utils.h> 34 #include <libidav/utils.h>
33 35
34 36
37
35 #define SETTINGS_STATE_REPOLIST_SELECTED 1 38 #define SETTINGS_STATE_REPOLIST_SELECTED 1
36
37 #define SETTINGS_STATE_REPO_ENCRYPTION 20 39 #define SETTINGS_STATE_REPO_ENCRYPTION 20
40 #define SETTINGS_STATE_CREDENTIALS_SELECTED 30
41 #define SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED 31
38 42
39 43
40 static void repolist_activate(UiEvent *event, void *userdata) { 44 static void repolist_activate(UiEvent *event, void *userdata) {
41 UiListSelection *selection = event->eventdata; 45 UiListSelection *selection = event->eventdata;
42 SettingsWindow *settings = event->window; 46 SettingsWindow *settings = event->window;
87 SettingsWindow *settings = event->window; 91 SettingsWindow *settings = event->window;
88 settings_store_repository(settings); 92 settings_store_repository(settings);
89 ui_set(settings->repo_tabview, 0); 93 ui_set(settings->repo_tabview, 0);
90 } 94 }
91 95
96 static void credentials_add(UiEvent *event, void *userdata) {
97 SettingsWindow *settings = event->window;
98 if(settings_credentials_save(settings)) {
99 return;
100 }
101 if(settings->credentials_list_needs_update) {
102 settings->credentials_ignore_selectionevent = TRUE;
103 ui_list_update(settings->credentials_users);
104 settings_reload_repo_credentials(settings);
105 settings->credentials_ignore_selectionevent = FALSE;
106 settings->credentials_list_needs_update = FALSE;
107 }
108 settings_credentials_clear(settings);
109 settings->credentials_new = TRUE;
110 PwdStore *pwd = settings->pwdstore;
111 if(!pwd->isdecrypted) {
112 settings_credentials_decrypt(settings);
113 return;
114 }
115 settings_credentials_select(settings, NULL);
116 }
117
118 static void credentials_remove(UiEvent *event, void *userdata) {
119 SettingsWindow *settings = event->window;
120 if(settings->credentials_selected_id) {
121 pwdstore_remove_entry(settings->pwdstore, settings->credentials_selected_id);
122 ui_list_remove(settings->credentials_users, settings->credentials_selected_index);
123 ui_list_update(settings->credentials_users);
124 settings_reload_repo_credentials(settings);
125 }
126 }
127
128 static void credentials_onselect(UiEvent *event, void *userdata) {
129 SettingsWindow *settings = event->window;
130 if(settings->credentials_ignore_selectionevent) {
131 return;
132 }
133 UiListSelection *sel = event->eventdata;
134 if(settings_credentials_save(settings)) {
135 return;
136 }
137 if(sel->count > 0) {
138 const char *id = ui_list_get(settings->credentials_users, sel->rows[0]);
139 settings->credentials_selected_index = sel->rows[0];
140 settings_credentials_select(settings, id);
141 if(settings->credentials_list_needs_update) {
142 settings->credentials_ignore_selectionevent = TRUE;
143 ui_list_update(settings->credentials_users);
144 settings_reload_repo_credentials(settings);
145 ui_list_setselection(settings->credentials_users, sel->rows[0]);
146 settings->credentials_ignore_selectionevent = FALSE;
147 settings->credentials_list_needs_update = FALSE;
148 }
149 } else {
150 settings_credentials_clear(settings);
151 }
152 }
153
154 static void c_add_location(UiEvent *event, void *userdata) {
155 SettingsWindow *settings = event->window;
156 if(event->intval == 1) {
157 ui_list_append(settings->credentials_locations, ui_strdup(event->obj->ctx, event->eventdata));
158 ui_list_update(settings->credentials_locations);
159 }
160 }
161
162 static void credentials_location_add(UiEvent *event, void *userdata) {
163 SettingsWindow *settings = event->window;
164 ui_dialog(event->obj,
165 .title = "Add Location",
166 .content = "New Location URL",
167 .input = TRUE,
168 .result = c_add_location,
169 .button1_label = "Add Location",
170 .closebutton_label = "Cancel");
171 }
172
173 static void c_edit_location(UiEvent *event, void *userdata) {
174 SettingsWindow *settings = event->window;
175 if(event->intval == 1) {
176 CxList *list = settings->credentials_locations->data;
177 ssize_t i = cxListFind(list, userdata);
178 if(i >= 0) {
179 cxListRemove(list, i);
180 cxListInsert(list, i, ui_strdup(event->obj->ctx, event->eventdata));
181 ui_list_update(settings->credentials_locations);
182 }
183 }
184 }
185
186 static void credentials_location_edit(UiEvent *event, void *userdata) {
187 SettingsWindow *settings = event->window;
188 char *location = ui_list_get(settings->credentials_locations, settings->credentials_location_selected_index);
189 ui_dialog(event->obj,
190 .title = "Edit Location",
191 .content = "Location URL",
192 .input_value = location,
193 .input = TRUE,
194 .result = c_edit_location,
195 .resultdata = location,
196 .button1_label = "Edit Location",
197 .closebutton_label = "Cancel");
198 }
199
200 static void credentials_location_remove(UiEvent *event, void *userdata) {
201 SettingsWindow *settings = event->window;
202 if(settings->credentials_location_selected_index >= 0) {
203 CxList *list = settings->credentials_locations->data;
204 cxListRemove(list, settings->credentials_location_selected_index);
205 ui_list_update(settings->credentials_locations);
206 }
207 }
208
209 static void credentials_location_up(UiEvent *event, void *userdata) {
210 SettingsWindow *settings = event->window;
211 int index = settings->credentials_location_selected_index;
212 if(index >= 1) {
213 CxList *list = settings->credentials_locations->data;
214 cxListSwap(list, index, index-1);
215 ui_list_update(settings->credentials_locations);
216 ui_list_setselection(settings->credentials_locations, index-1);
217 }
218 }
219
220 static void credentials_location_down(UiEvent *event, void *userdata) {
221 SettingsWindow *settings = event->window;
222 int index = settings->credentials_location_selected_index;
223 if(index >= 0 && index + 1 < ui_list_count(settings->credentials_locations)) {
224 CxList *list = settings->credentials_locations->data;
225 cxListSwap(list, index, index+1);
226 ui_list_update(settings->credentials_locations);
227 ui_list_setselection(settings->credentials_locations, index+1);
228 }
229 }
230
231 static void credentials_location_onselect(UiEvent *event, void *userdata) {
232 SettingsWindow *settings = event->window;
233 UiListSelection *sel = event->eventdata;
234 if(sel->count > 0) {
235 settings->credentials_location_selected_index = sel->rows[0];
236 ui_set_group(event->obj->ctx, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED);
237 } else {
238 settings->credentials_location_selected_index = -1;
239 ui_unset_group(event->obj->ctx, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED);
240 }
241 }
242
243 static void credentials_setmasterpw(UiEvent *event, void *userdata) {
244 if(event->intval == 1) {
245 SettingsWindow *settings = event->window;
246 char *pw = event->eventdata;
247 size_t pwlen = strlen(pw);
248 if(pwlen > 0) {
249 pwdstore_setpassword(settings->pwdstore, event->eventdata);
250 memset(pw, 0, pwlen);
251 if(!pwdstore_decrypt(settings->pwdstore)) {
252 settings_credentials_select(settings, NULL);
253 } else {
254 ui_dialog(event->obj, .title = "Error", .content = "Cannot decrypt Secret Store", .closebutton_label = "OK");
255 }
256 }
257 }
258 }
259
260 void settings_credentials_decrypt(SettingsWindow *settings) {
261 ui_dialog(settings->obj,
262 .title = "Secret Store",
263 .content = "Master password",
264 .password = TRUE,
265 .result = credentials_setmasterpw,
266 .button1_label = "Decrypt Secret Store",
267 .closebutton_label = "Cancel");
268 }
269
270 static void list_str_destructor(void *data, void *ptr) {
271 UiContext *ctx = data;
272 char *s = ptr;
273 ui_free(ctx, ptr);
274 }
275
92 276
93 void settings_ok(UiEvent *event, void *userdata) { 277 void settings_ok(UiEvent *event, void *userdata) {
94 SettingsWindow *settings = event->window; 278 SettingsWindow *settings = event->window;
95 settings->config_saved = TRUE; 279 settings->config_saved = TRUE;
96 // save any changed settings 280 // save any changed settings
97 settings_store_repository(settings); 281 settings_store_repository(settings);
282 settings_credentials_save(settings);
98 283
99 set_config(settings->config); // TODO: free old config 284 set_config(settings->config); // TODO: free old config
100 if(store_config()) { 285 if(store_config()) {
101 ui_dialog(event->obj, .title = "Error", .content = "Cannot store settings", .closebutton_label = "OK"); 286 ui_dialog(event->obj, .title = "Error", .content = "Cannot store settings", .closebutton_label = "OK");
287 }
288 settings->config = NULL;
289 if(settings->credentials_modified) {
290 set_pwdstore(settings->pwdstore);
291 pwdstore_save(settings->pwdstore);
292 settings->pwdstore = NULL;
102 } 293 }
103 application_update_repolist(get_application()); 294 application_update_repolist(get_application());
104 ui_close(event->obj); 295 ui_close(event->obj);
105 } 296 }
106 297
110 // function was called as context closefunc by ui_close 301 // function was called as context closefunc by ui_close
111 // in settings_ok 302 // in settings_ok
112 // don't free anything 303 // don't free anything
113 return; 304 return;
114 } 305 }
115 dav_config_free(settings->config); 306 if(settings->config) {
307 dav_config_free(settings->config);
308 }
309 if(settings->pwdstore) {
310 pwdstore_free(settings->pwdstore);
311 }
116 } 312 }
117 313
118 void settings_cancel(UiEvent *event, void *userdata) { 314 void settings_cancel(UiEvent *event, void *userdata) {
119 SettingsWindow *settings = event->window; 315 SettingsWindow *settings = event->window;
120 ui_close(event->obj); 316 ui_close(event->obj);
123 void settings_window_open() { 319 void settings_window_open() {
124 DavConfig *config = load_config_file(); 320 DavConfig *config = load_config_file();
125 if(!config) { 321 if(!config) {
126 return; 322 return;
127 } 323 }
324 PwdStore *pwdstore = get_pwdstore();
325 pwdstore = !pwdstore ? pwdstore_new() : pwdstore_clone(pwdstore);
128 326
129 UiObject *obj = ui_simple_window("Settings", NULL); 327 UiObject *obj = ui_simple_window("Settings", NULL);
130 ui_context_closefunc(obj->ctx, settings_close, NULL); 328 ui_context_closefunc(obj->ctx, settings_close, NULL);
131 SettingsWindow *wdata = ui_malloc(obj->ctx, sizeof(SettingsWindow)); 329 SettingsWindow *wdata = ui_malloc(obj->ctx, sizeof(SettingsWindow));
330 memset(wdata, 0, sizeof(SettingsWindow));
132 wdata->config = config; 331 wdata->config = config;
332 wdata->pwdstore = pwdstore;
133 obj->window = wdata; 333 obj->window = wdata;
334 wdata->obj = obj;
134 settings_init(obj, wdata); 335 settings_init(obj, wdata);
135 336
136 ui_tabview(obj) { 337 ui_tabview(obj) {
137 ui_tab(obj, "General") { 338 ui_tab(obj, "General") {
138 ui_grid(obj, .margin = 10) { 339 ui_grid(obj, .margin = 10) {
245 ui_label(obj, .label = "TODO"); 446 ui_label(obj, .label = "TODO");
246 } 447 }
247 } 448 }
248 449
249 ui_tab(obj, "Credentials") { 450 ui_tab(obj, "Credentials") {
250 ui_grid(obj, .margin = 10) { 451 ui_hbox(obj, .margin = 10, .spacing = 10) {
251 ui_label(obj, .label = "TODO"); 452 ui_vbox(obj, .fill = UI_OFF) {
453 ui_listview(obj, .list = wdata->credentials_users, .fill = UI_ON, .onselection = credentials_onselect);
454 ui_hbox(obj, .fill = UI_OFF, .spacing = 4) {
455 ui_button(obj, .label = "Add", .onclick = credentials_add);
456 ui_button(obj, .label = "Remove", .onclick = credentials_remove, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
457 }
458 }
459
460 ui_grid(obj, .columnspacing = 30, .rowspacing = 10) {
461 ui_llabel(obj, .label = "Identifier");
462 ui_textfield(obj, .value = wdata->credentials_id, .hexpand = TRUE, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
463 ui_newline(obj);
464
465 ui_llabel(obj, .label = "User");
466 ui_textfield(obj, .value = wdata->credentials_user, .hexpand = TRUE, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
467 ui_newline(obj);
468
469 ui_llabel(obj, .label = "Password");
470 ui_passwordfield(obj, .value = wdata->credentials_password, .hexpand = TRUE, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
471 ui_newline(obj);
472
473 ui_label(obj, .label = " ");
474 ui_newline(obj);
475
476 ui_llabel(obj, .style = UI_LABEL_STYLE_TITLE, .label = "Locations", .colspan = 2);
477 ui_newline(obj);
478 ui_llabel(obj, .style = UI_LABEL_STYLE_DIM, .label = "List of URLs for which these credentials should be used (optional)", .colspan = 2);
479 ui_newline(obj);
480
481 ui_hbox(obj, .colspan = 2, .vexpand = TRUE, .hexpand = TRUE, .spacing = 10) {
482 ui_listview(obj, .list = wdata->credentials_locations, .onactivate = credentials_location_edit, .onselection = credentials_location_onselect, .colspan = 2, .fill = UI_ON, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
483 ui_vbox(obj, .fill = UI_OFF, .spacing = 4) {
484 ui_button(obj, .label = "Add", .onclick = credentials_location_add, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED));
485 ui_button(obj, .label = "Edit", .onclick = credentials_location_edit, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED));
486 ui_button(obj, .label = "Remove", .onclick = credentials_location_remove, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED));
487 ui_button(obj, .label = "Move Up", .onclick = credentials_location_up, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED));
488 ui_button(obj, .label = "Move Down", .onclick = credentials_location_down, .groups = UI_GROUPS(SETTINGS_STATE_CREDENTIALS_SELECTED, SETTINGS_STATE_CREDENTIALS_LOCATION_SELECTED));
489 }
490 }
491 }
252 } 492 }
253 } 493 }
254 494
255 ui_tab(obj, "Keys") { 495 ui_tab(obj, "Keys") {
256 ui_grid(obj, .margin = 10) { 496 ui_grid(obj, .margin = 10) {
262 ui_grid(obj, .margin = 10) { 502 ui_grid(obj, .margin = 10) {
263 ui_label(obj, .label = "TODO"); 503 ui_label(obj, .label = "TODO");
264 } 504 }
265 } 505 }
266 } 506 }
267 507
268 ui_hbox(obj, .fill = UI_OFF, .margin = 10) { 508 ui_hbox(obj, .fill = UI_OFF, .margin = 10) {
269 ui_button(obj, .label = "Cancel", .onclick = settings_cancel); 509 ui_button(obj, .label = "Cancel", .onclick = settings_cancel);
270 ui_label(obj, .fill = UI_ON); 510 ui_label(obj, .fill = UI_ON);
271 ui_button(obj, .label = "Save", .onclick = settings_ok); 511 ui_button(obj, .label = "Save", .onclick = settings_ok);
272 } 512 }
287 settings->repo_credentials = ui_list_new(obj->ctx, NULL); 527 settings->repo_credentials = ui_list_new(obj->ctx, NULL);
288 settings->repo_keys = ui_list_new(obj->ctx, NULL); 528 settings->repo_keys = ui_list_new(obj->ctx, NULL);
289 settings->repo_tls_versions = ui_list_new(obj->ctx, NULL); 529 settings->repo_tls_versions = ui_list_new(obj->ctx, NULL);
290 settings->repo_encryption = ui_int_new(obj->ctx, NULL); 530 settings->repo_encryption = ui_int_new(obj->ctx, NULL);
291 settings->repo_disable_verification = ui_int_new(obj->ctx, NULL); 531 settings->repo_disable_verification = ui_int_new(obj->ctx, NULL);
292 532
293 ui_list_append(settings->repo_tls_versions, "Default"); 533 ui_list_append(settings->repo_tls_versions, "Default");
294 ui_list_append(settings->repo_tls_versions, "TLSv1.3"); 534 ui_list_append(settings->repo_tls_versions, "TLSv1.3");
295 ui_list_append(settings->repo_tls_versions, "TLSv1.2"); 535 ui_list_append(settings->repo_tls_versions, "TLSv1.2");
296 ui_list_append(settings->repo_tls_versions, "TLSv1.1"); 536 ui_list_append(settings->repo_tls_versions, "TLSv1.1");
297 ui_list_append(settings->repo_tls_versions, "TLSv1.0"); 537 ui_list_append(settings->repo_tls_versions, "TLSv1.0");
298 538
539 settings->credentials_selected_index = -1;
540 settings->credentials_users = ui_list_new(obj->ctx, NULL);
541 settings->credentials_locations = ui_list_new(obj->ctx, NULL);
542 settings->credentials_id = ui_string_new(obj->ctx, NULL);
543 settings->credentials_user = ui_string_new(obj->ctx, NULL);
544 settings->credentials_password = ui_string_new(obj->ctx, NULL);
545 CxList *credentials_users = settings->credentials_users->data;
546 CxList *credentials_locations = settings->credentials_locations->data;
547 credentials_users->collection.advanced_destructor = list_str_destructor;
548 credentials_users->collection.destructor_data = settings->obj->ctx;
549 credentials_users->collection.cmpfunc = (cx_compare_func)strcmp;
550 credentials_locations->collection.advanced_destructor = list_str_destructor;
551 credentials_locations->collection.destructor_data = settings->obj->ctx;
552 credentials_locations->collection.cmpfunc = (cx_compare_func)strcmp;
553
299 // load some list values, that can be reused 554 // load some list values, that can be reused
300 settings_update_repolist(settings); 555 settings_update_repolist(settings);
301 settings_reload_keys(settings); 556 settings_reload_keys(settings);
302 settings_reload_credentials(settings); 557 settings_reload_credentials(settings);
558 void settings_reload_repo_credentials(SettingsWindow *settings);
303 559
304 settings->selected_repo = -1; 560 settings->selected_repo = -1;
305 } 561 }
306 562
307 #define SETTINGS_SET_STRING(str, setting) if(setting.value.ptr) ui_set(str, setting.value.ptr); 563 #define SETTINGS_SET_STRING(str, setting) if(setting.value.ptr) ui_set(str, setting.value.ptr);
564
565 /* ----------------------------- Repository ----------------------------- */
308 566
309 void settings_edit_repository(SettingsWindow *settings, int repo_index) { 567 void settings_edit_repository(SettingsWindow *settings, int repo_index) {
310 DavCfgRepository *repo = ui_list_get(settings->repos, repo_index); 568 DavCfgRepository *repo = ui_list_get(settings->repos, repo_index);
311 if(!repo) { 569 if(!repo) {
312 fprintf(stderr, "Error: cannot get repository at index %d\n", repo_index); 570 fprintf(stderr, "Error: cannot get repository at index %d\n", repo_index);
564 } 822 }
565 #endif 823 #endif
566 return NULL; 824 return NULL;
567 } 825 }
568 826
827
828 /* ----------------------------- Credentials ----------------------------- */
829
569 void settings_reload_credentials(SettingsWindow *settings) { 830 void settings_reload_credentials(SettingsWindow *settings) {
570 PwdStore *pwd = get_pwdstore(); 831 PwdStore *pwd = settings->pwdstore;
571 if(!pwd) { 832
572 return; 833 ui_list_clear(settings->credentials_users);
573 }
574
575 ui_list_clear(settings->repo_credentials);
576 ui_list_append(settings->repo_credentials, "-");
577 834
578 CxIterator i = cxListIterator(pwd->noloc); 835 CxIterator i = cxListIterator(pwd->noloc);
579 cx_foreach(PwdIndexEntry*, entry, i) { 836 cx_foreach(PwdIndexEntry*, entry, i) {
580 ui_list_append(settings->repo_credentials, entry->id); 837 char *id = ui_strdup(settings->obj->ctx, entry->id);
838 ui_list_append(settings->credentials_users, id);
581 } 839 }
582 i = cxListIterator(pwd->locations); 840 i = cxListIterator(pwd->locations);
583 cx_foreach(PwdIndexEntry*, entry, i) { 841 cx_foreach(PwdIndexEntry*, entry, i) {
584 ui_list_append(settings->repo_credentials, entry->id); 842 char *id = ui_strdup(settings->obj->ctx, entry->id);
585 } 843 ui_list_append(settings->credentials_users, id);
586 844 }
587 if(settings->repo_credentials->update) { 845
588 ui_list_update(settings->repo_credentials); 846 ui_list_update(settings->credentials_users);
589 } 847 }
590 } 848
591 849 void settings_reload_repo_credentials(SettingsWindow *settings) {
592 850 PwdStore *pwd = settings->pwdstore;
851
852 ui_list_clear(settings->repo_credentials);
853
854 // repo_credentials needs an entry for selecting no credentials
855 ui_list_append(settings->repo_credentials, "-");
856
857 CxIterator i = cxListIterator(pwd->noloc);
858 cx_foreach(PwdIndexEntry*, entry, i) {
859 char *id = ui_strdup(settings->obj->ctx, entry->id);
860 ui_list_append(settings->repo_credentials, id);
861 }
862 i = cxListIterator(pwd->locations);
863 cx_foreach(PwdIndexEntry*, entry, i) {
864 char *id = ui_strdup(settings->obj->ctx, entry->id);
865 ui_list_append(settings->repo_credentials, id);
866 }
867
868 ui_list_update(settings->repo_credentials);
869 }
870
871
872 void settings_credentials_select(SettingsWindow *settings, const char *id) {
873 if(!id && !settings->credentials_selected_id && !settings->credentials_new) {
874 fprintf(stderr, "Error: no credentials id selected\n");
875 return;
876 }
877
878 PwdStore *pwd = settings->pwdstore;
879
880 if(id) {
881 ui_free(settings->obj->ctx, settings->credentials_selected_id);
882 settings->credentials_selected_id = ui_strdup(settings->obj->ctx, id);
883 }
884
885 if(!pwd->isdecrypted) {
886 settings_credentials_decrypt(settings);
887 return;
888 }
889
890 if(settings->credentials_new) {
891 ui_free(settings->obj->ctx, settings->credentials_selected_id);
892 settings->credentials_selected_id = NULL;
893 settings->credentials_selected_index = ui_list_count(settings->credentials_users);
894 ui_list_append(settings->credentials_users, ui_strdup(settings->obj->ctx, "new"));
895 settings->credentials_ignore_selectionevent = TRUE;
896 ui_list_update(settings->credentials_users);
897 ui_list_setselection(settings->credentials_users, settings->credentials_selected_index);
898 settings->credentials_ignore_selectionevent = FALSE;
899
900 ui_set(settings->credentials_id, "new");
901 ui_set(settings->credentials_user, "");
902 ui_set(settings->credentials_password, "");
903 ui_list_clear(settings->credentials_locations);
904 ui_list_update(settings->credentials_locations);
905 } else {
906 PwdEntry *entry = cxMapGet(pwd->ids, settings->credentials_selected_id);
907 PwdIndexEntry *index = cxMapGet(pwd->index, settings->credentials_selected_id);
908 if(!entry) {
909 fprintf(stderr, "Error: cannot get pwd entry %s\n", settings->credentials_selected_id);
910 return;
911 }
912 if(!index) {
913 fprintf(stderr, "Error: missing PwdIndexEntry. PwdStore may be broken.\n");
914 return;
915 }
916
917 ui_set(settings->credentials_id, entry->id);
918 ui_set(settings->credentials_user, entry->user);
919 ui_set(settings->credentials_password, entry->password);
920
921 ui_list_clear(settings->credentials_locations);
922 if(index->locations) {
923 CxIterator i = cxListIterator(index->locations);
924 cx_foreach(char *, loc, i) {
925 ui_list_append(settings->credentials_locations, ui_strdup(settings->obj->ctx, loc));
926 }
927 }
928 }
929
930 ui_list_update(settings->credentials_locations);
931
932 ui_set_group(settings->obj->ctx, SETTINGS_STATE_CREDENTIALS_SELECTED);
933 }
934
935 void settings_credentials_clear(SettingsWindow *settings) {
936 ui_free(settings->obj->ctx, settings->credentials_selected_id);
937 settings->credentials_selected_id = NULL;
938 settings->credentials_new = FALSE;
939
940 ui_set(settings->credentials_id, "");
941 ui_set(settings->credentials_user, "");
942 ui_set(settings->credentials_password, "");
943 ui_list_clear(settings->credentials_locations);
944 ui_list_update(settings->credentials_locations);
945
946 ui_unset_group(settings->obj->ctx, SETTINGS_STATE_CREDENTIALS_SELECTED);
947 }
948
949 int settings_credentials_save(SettingsWindow *settings) {
950 if(settings->credentials_selected_index == -1) {
951 return 0;
952 }
953
954 // check if the credentials list contains an element with the same id
955 // if an index is found, it must match the selected index, otherwise
956 // we have a duplicate identifier
957 char *newid = ui_get(settings->credentials_id);
958 if(strlen(newid) == 0) {
959 return 0; // TODO: check if other fields are set
960 }
961
962 ssize_t index = cxListFind(settings->credentials_users->data, newid);
963 if(index >=0 && index != settings->credentials_selected_index) {
964 cxmutstr s = cx_asprintf("Identifier %s already in use", newid);
965 ui_dialog(settings->obj, .title = "Error", .content = s.ptr, .closebutton_label = "OK");
966 free(s.ptr);
967 return 1;
968 }
969
970 char *user = ui_get(settings->credentials_user);
971 char *password = ui_get(settings->credentials_password);
972 CxList *ui_locations = settings->credentials_locations->data;
973 size_t numlocations = cxListSize(ui_locations);
974 CxList *locations = NULL;
975 if(numlocations > 0) {
976 locations = cxArrayListCreateSimple(CX_STORE_POINTERS, numlocations);
977 CxIterator i = cxListIterator(ui_locations);
978 cx_foreach(char*, loc, i) {
979 cxListAdd(locations, strdup(loc));
980 }
981 }
982
983 // if the user id changed, mark the list as changed to update it later
984 settings->credentials_list_needs_update = settings->credentials_new || strcmp(newid, settings->credentials_selected_id);
985 if(settings->credentials_new || strcmp(newid, settings->credentials_selected_id ? settings->credentials_selected_id : "")) {
986 settings->credentials_list_needs_update = TRUE;
987 cxListRemove(settings->credentials_users->data, settings->credentials_selected_index);
988 cxListInsert(settings->credentials_users->data, settings->credentials_selected_index, ui_strdup(settings->obj->ctx, newid));
989 }
990
991 // if the pwdstore already contains this id, remove it first
992 if(settings->credentials_selected_id) {
993 pwdstore_remove_entry(settings->pwdstore, settings->credentials_selected_id);
994 }
995
996 pwdstore_put(settings->pwdstore, newid, user, password);
997 pwdstore_put_index(settings->pwdstore, strdup(newid), locations);
998 settings->credentials_modified = TRUE;
999 settings->credentials_new = FALSE;
1000
1001 return 0;
1002 }

mercurial