--- a/application/davcontroller.c Thu Nov 14 22:28:36 2024 +0100 +++ b/application/davcontroller.c Thu Nov 14 23:22:35 2024 +0100 @@ -78,13 +78,101 @@ // ------------------------------ davbrowser_connect2repo ------------------------------ -void davbrowser_connect2repo(UiObject *ui, DavBrowser *browser, DavCfgRepository *repo, const char *path) { - DavSession *sn = dav_session_new(application_dav_context(), repo->url.value.ptr); +typedef struct DavConnect2Repo { + UiObject *ui; + DavBrowser *browser; + + DavCfgRepository *repo; + char *path; + + UiString *password; +} DavConnect2Repo; + +static void dialog_secretstore_decrypt(UiEvent *event, void *data) { + DavConnect2Repo *c2r = event->window; + + if(event->intval == 4) { + char *pw = ui_get(c2r->password); + + PwdStore *secrets = get_pwdstore(); + pwdstore_setpassword(secrets, pw); + if(pwdstore_decrypt(secrets)) { + ui_dialog(c2r->ui, .title = "Error", .content = "Cannot decrypt Secret Store", .closebutton_label = "OK"); + } else { + davbrowser_connect2repo(c2r->ui, c2r->browser, c2r->repo, c2r->path); + } + } + free(c2r->path); + if(!c2r->repo->node) { + dav_repository_free(get_config(), c2r->repo); + } + + ui_close(event->obj); +} + +int davbrowser_connect2repo(UiObject *ui, DavBrowser *browser, DavCfgRepository *repo, const char *path) { + char *user = NULL; + char *password = NULL; + char *password_free = NULL; if (repo->user.value.ptr && repo->password.value.ptr) { + user = repo->user.value.ptr; cxmutstr decodedpw = dav_repository_get_decodedpassword(repo); - dav_session_set_auth(sn, repo->user.value.ptr, decodedpw.ptr); - free(decodedpw.ptr); + password = decodedpw.ptr; + password_free = decodedpw.ptr; + } else { + PwdStore *secrets = get_pwdstore(); + const char *credentials = NULL; + if(repo->stored_user.value.ptr) { + if(pwdstore_has_id(secrets, repo->stored_user.value.ptr)) { + credentials = repo->stored_user.value.ptr; + } + } else { + credentials = get_location_credentials(repo, path); + } + + if(credentials) { + if(!secrets->isdecrypted) { + UiObject *obj = ui_dialog_window(ui, + .title = "Authentication", + .lbutton1 = "Cancel", + .rbutton4 = "Connect", + .default_button = 4, + .show_closebutton = UI_OFF, + .onclick = dialog_secretstore_decrypt); + + DavConnect2Repo *c2r = ui_malloc(obj->ctx, sizeof(DavConnect2Repo)); + c2r->ui = ui; + c2r->browser = browser; + c2r->repo = repo; + c2r->path = path ? strdup(path) : NULL; + c2r->password = ui_string_new(obj->ctx, NULL); + obj->window = c2r; + + ui_grid(obj, .margin = 20, .columnspacing = 12, .rowspacing = 16) { + ui_llabel(obj, .label = "Decrypt Secret Store", .colspan = 2); + ui_newline(obj); + + ui_llabel(obj, .label = "Password"); + ui_passwordfield(obj, .value = c2r->password, .hexpand = TRUE); + } + + ui_show(obj); + + return 1; + } + + if(!get_stored_credentials(credentials, &user, &password)) { + fprintf(stderr, "Error: failed to get user/password for credentials %s\n", credentials); + } + } } + + DavSession *sn = dav_session_new(application_dav_context(), repo->url.value.ptr); + if (user && password) { + dav_session_set_auth(sn, user, password); + } + free(password_free); + browser->sn = sn; if (repo->name.value.length > 0) { browser->repo_base = cx_strdup(cx_strn(repo->name.value.ptr, repo->name.value.length)).ptr; @@ -105,6 +193,8 @@ dav_session_set_authcallback(sn, jobthr_davbrowser_auth, auth); davbrowser_query_path(ui, browser, path); + + return 0; } // ------------------------------ davbrowser_auth ------------------------------ @@ -232,11 +322,13 @@ char *path = NULL; DavCfgRepository *repo = dav_config_url2repo(get_config(), url, &path); - davbrowser_connect2repo(ui, browser, repo, path); + + int ret = davbrowser_connect2repo(ui, browser, repo, path); + free(path); + if(ret) { + return; + } - if (path) { - free(path); - } if (!repo->node) { dav_repository_free(get_config(), repo); }