diff options
| author | Anders Betts <anders.betts@gmail.com> | 2026-09-17 22:30:33 +0200 |
|---|---|---|
| committer | Anders Betts <anders.betts@gmail.com> | 2026-09-17 22:30:33 +0200 |
| commit | 804b31cc0c8415ebc79ccddf534dd09c5e6484a0 (patch) | |
| tree | 4e5222126e358d0ea34a63b2fab45102e8c03c24 /clients/bokftui.c | |
| parent | 91f2af4f5ce2f295c5d0a8bfd22b8c3bcc5f6966 (diff) | |
| download | bokf-804b31cc0c8415ebc79ccddf534dd09c5e6484a0.tar.gz bokf-804b31cc0c8415ebc79ccddf534dd09c5e6484a0.zip | |
bokftui: remember server/user, BOKFD_TOKEN auto-login, sudo credential launcherv0.1.4
Diffstat (limited to 'clients/bokftui.c')
| -rw-r--r-- | clients/bokftui.c | 162 |
1 files changed, 143 insertions, 19 deletions
diff --git a/clients/bokftui.c b/clients/bokftui.c index c26d188..16c9941 100644 --- a/clients/bokftui.c +++ b/clients/bokftui.c @@ -3837,13 +3837,116 @@ static void dashboard(struct app *a) /* login */ /* ------------------------------------------------------------------ */ +/* The login screen remembers server and user (never the password) in + $XDG_CONFIG_HOME/bokf/tui.conf, defaulting to ~/.config/bokf/tui.conf. */ + +static void config_path(char *buf, size_t n) +{ + const char *xdg = getenv("XDG_CONFIG_HOME"); + if (xdg && *xdg) { + snprintf(buf, n, "%s/bokf/tui.conf", xdg); + return; + } + const char *home = getenv("HOME"); + snprintf(buf, n, "%s/.config/bokf/tui.conf", + home && *home ? home : "."); +} + +static void config_mkdirs(const char *path) +{ + char tmp[512]; + snprintf(tmp, sizeof tmp, "%s", path); + if (strlen(tmp) >= sizeof tmp) + return; + for (char *p = tmp + 1; *p; p++) { + if (*p != '/') + continue; + *p = '\0'; + mkdir(tmp, 0700); + *p = '/'; + } +} + +static void config_load(struct app *a) +{ + char path[512]; + config_path(path, sizeof path); + FILE *f = fopen(path, "r"); + if (!f) + return; + char line[512]; + while (fgets(line, sizeof line, f)) { + char *nl = strchr(line, '\n'); + if (nl) + *nl = '\0'; + char *eq = strchr(line, '='); + if (!eq) + continue; + *eq = '\0'; + const char *val = util_str_trim(eq + 1); + if (strcmp(line, "server") == 0 && !a->socket[0]) + snprintf(a->socket, sizeof a->socket, "%s", val); + else if (strcmp(line, "user") == 0 && !a->username[0]) + snprintf(a->username, sizeof a->username, "%s", val); + } + fclose(f); +} + +static void config_save(const struct app *a) +{ + char path[512]; + config_path(path, sizeof path); + config_mkdirs(path); + FILE *f = fopen(path, "w"); + if (!f) + return; + fprintf(f, "server=%s\nuser=%s\n", a->socket, a->username); + fclose(f); + chmod(path, 0600); +} + +/* Connects and opens a session. Returns 0 on success, -2 when the + connection failed and -1 when the server rejected the login. */ +static int try_login(struct app *a, const char *user, const char *pass, + const char *token, char **err_out) +{ + *err_out = NULL; + if (client_connect(a->socket, &a->conn) != 0) { + *err_out = xstrdup(client_last_error()); + return -2; + } + char *session = NULL; + int rc; + if (token && *token) + rc = client_token_login(&a->conn, token, &session, err_out); + else + rc = client_login(&a->conn, user, pass, &session, err_out); + if (rc != 0) { + client_close(&a->conn); + return -1; + } + snprintf(a->session, sizeof a->session, "%s", session); + if (user && *user) + snprintf(a->username, sizeof a->username, "%s", user); + free(session); + if (token && *token) { + char *resp = + client_rpc(&a->conn, "session.whoami", a->session, 0, NULL); + char *u = jstr_dup(resp, "result.user.username"); + if (u && *u) + snprintf(a->username, sizeof a->username, "%s", u); + free(u); + free(resp); + } + return 0; +} + static int login_screen(struct app *a) { char socket_path[256], user[64], pass[128]; snprintf(socket_path, sizeof socket_path, "%s", a->socket); - const char *env_user = getenv("BOKFD_USER"); const char *env_pass = getenv("BOKFD_PASSWORD"); - snprintf(user, sizeof user, "%s", env_user ? env_user : ""); + snprintf(user, sizeof user, "%s", a->username); snprintf(pass, sizeof pass, "%s", env_pass ? env_pass : ""); int field = 3; /* 0 server, 1 user, 2 password, 3 = Logga in button */ @@ -3936,13 +4039,15 @@ static int login_screen(struct app *a) /* attempt login */ snprintf(a->socket, sizeof a->socket, "%s", socket_path); - if (client_connect(a->socket, &a->conn) != 0) { + char *err = NULL; + int rc = try_login(a, user, pass, NULL, &err); + if (rc == -2) { message("Fel", "Kunde inte ansluta till %s: %s", a->socket, - client_last_error()); + err ? err : "okänt fel"); + free(err); continue; } - char *err = NULL, *session = NULL; - if (client_login(&a->conn, user, pass, &session, &err) != 0) { + if (rc != 0) { if (err && err[0] == '{') { char *code = jstr_dup(err, "error.code"); char *msg = jstr_dup(err, "error.message"); @@ -3955,12 +4060,9 @@ static int login_screen(struct app *a) err ? err : "transportfel"); } free(err); - client_close(&a->conn); continue; } - snprintf(a->session, sizeof a->session, "%s", session); - snprintf(a->username, sizeof a->username, "%s", user); - free(session); + config_save(a); return 0; } } @@ -4025,16 +4127,14 @@ int main(int argc, char **argv) struct app app; memset(&app, 0, sizeof app); app.conn.fd = -1; - const char *socket = getenv("BOKFD_SOCKET"); - if (!socket) - socket = "/run/bokfd/bokfd.sock"; + const char *cli_socket = NULL, *cli_user = NULL; int64_t want_org = 0; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "--socket") == 0 && i + 1 < argc) - socket = argv[++i]; - else if (strcmp(argv[i], "--user") == 0 && i + 1 < argc) { - (void)argv[++i]; - } else if (strcmp(argv[i], "--org") == 0 && i + 1 < argc) { + cli_socket = argv[++i]; + else if (strcmp(argv[i], "--user") == 0 && i + 1 < argc) + cli_user = argv[++i]; + else if (strcmp(argv[i], "--org") == 0 && i + 1 < argc) { want_org = strtoll(argv[++i], NULL, 10); } else if (strcmp(argv[i], "--version") == 0) { printf("bokftui %s\n", BOKF_VERSION); @@ -4047,7 +4147,20 @@ int main(int argc, char **argv) return 2; } } - snprintf(app.socket, sizeof app.socket, "%s", socket); + const char *env_socket = getenv("BOKFD_SOCKET"); + const char *env_user = getenv("BOKFD_USER"); + if (cli_socket) + snprintf(app.socket, sizeof app.socket, "%s", cli_socket); + else if (env_socket) + snprintf(app.socket, sizeof app.socket, "%s", env_socket); + if (cli_user) + snprintf(app.username, sizeof app.username, "%s", cli_user); + else if (env_user) + snprintf(app.username, sizeof app.username, "%s", env_user); + config_load(&app); + if (!app.socket[0]) + snprintf(app.socket, sizeof app.socket, "%s", + "/run/bokfd/bokfd.sock"); setlocale(LC_ALL, ""); initscr(); @@ -4057,7 +4170,18 @@ int main(int argc, char **argv) keypad(stdscr, TRUE); curs_set(1); - if (login_screen(&app) != 0) { + const char *token = getenv("BOKFD_TOKEN"); + if (token && *token) { + char *err = NULL; + if (try_login(&app, NULL, NULL, token, &err) == 0) { + config_save(&app); + } else { + message("Token", "Token-inloggning misslyckades: %s", + err ? err : "okänt fel"); + free(err); + } + } + if (!app.session[0] && login_screen(&app) != 0) { endwin(); return 0; } |
