git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] credential: let helpers tell us to quit

From
Jeff King <peff@peff.net>
Date
Dec 4, 2014, 03:46 UTC
Message-ID
<20141204034647.GA21492@peff.net>
In-Reply-To
<20141204034206.GA1493@peff.net>

When we are trying to fill a credential, we loop over the set of defined credential-helpers, then fall back to running askpass, and then finally prompt on the terminal. Helpers which cannot find a credential are free to tell us nothing, but they cannot currently ask us to stop prompting.

This patch lets them provide a "quit" attribute, which asks us to stop the process entirely (avoiding running more helpers, as well as the askpass/terminal prompt).

This has a few possible uses:
  1. A helper which prompts the user itself (e.g., in a
     dialog) can provide a "cancel" button to the user to
     stop further prompts.
  2. Some helpers may know that prompting cannot possibly
     work. For example, if their role is to broker a ticket
     from an external auth system and that auth system
     cannot be contacted, there is no point in continuing
     (we need a ticket to authenticate, and the user cannot
     provide one by typing it in).
Signed-off-by: Jeff King <peff@peff.net>
---
+cc spearce, as I recall that you may do something similar to the second
scenario (and this would prevent annoying useless prompts when the
helper fails).
 Documentation/technical/api-credentials.txt | 5 ++++-
 credential.c                                | 5 +++++
 credential.h                                | 1 +
 t/t0300-credentials.sh                      | 9 +++++++++
 4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt
index c1b42a4..e44426d 100644
--- a/Documentation/technical/api-credentials.txt
+++ b/Documentation/technical/api-credentials.txt
@@ -248,7 +248,10 @@ FORMAT` in linkgit:git-credential[7] for a detailed specification).
 For a `get` operation, the helper should produce a list of attributes
 on stdout in the same format. A helper is free to produce a subset, or
 even no values at all if it has nothing useful to provide. Any provided
-attributes will overwrite those already known about by Git.
+attributes will overwrite those already known about by Git.  If a helper
+outputs a `quit` attribute with a value of `true` or `1`, no further
+helpers will be consulted, nor will the user be prompted (if no
+credential has been provided, the operation will then fail).
 
 For a `store` or `erase` operation, the helper's output is ignored.
 If it fails to perform the requested operation, it may complain to
diff --git a/credential.c b/credential.c
index 1886ea5..b146ad8 100644
--- a/credential.c
+++ b/credential.c
@@ -173,6 +173,8 @@ int credential_read(struct credential *c, FILE *fp)
 			c->path = xstrdup(value);
 		} else if (!strcmp(key, "url")) {
 			credential_from_url(c, value);
+		} else if (!strcmp(key, "quit")) {
+			c->quit = !!git_config_bool("quit", value);
 		}
 		/*
 		 * Ignore other lines; we don't know what they mean, but
@@ -274,6 +276,9 @@ void credential_fill(struct credential *c)
 		credential_do(c, c->helpers.items[i].string, "get");
 		if (c->username && c->password)
 			return;
+		if (c->quit)
+			die("credential helper '%s' told us to quit",
+			    c->helpers.items[i].string);
 	}
 
 	credential_getpass(c);
diff --git a/credential.h b/credential.h
index 0c3e85e..6b0cd16 100644
--- a/credential.h
+++ b/credential.h
@@ -7,6 +7,7 @@ struct credential {
 	struct string_list helpers;
 	unsigned approved:1,
 		 configured:1,
+		 quit:1,
 		 use_http_path:1;
 
 	char *username;
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 57ea5a1..d7ef44b 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -289,4 +289,13 @@ test_expect_success 'http paths can be part of context' '
 	EOF
 '
 
+test_expect_success 'helpers can abort the process' '
+	test_must_fail git \
+		-c credential.helper="!f() { echo quit=1; }; f" \
+		-c credential.helper="verbatim foo bar" \
+		credential fill >stdout &&
+	>expect &&
+	test_cmp expect stdout
+'
+
 test_done
-- 
2.2.0.390.gf60752d
Previous: Jeff KingNext: Jeff King
Message 11 of 17 in “Disabling credential helper?”
  1. brian m. carlsonDec 3, 2014
  2. Jonathan NiederDec 3, 2014
  3. Jeff KingDec 3, 2014
  4. Jonathan NiederDec 3, 2014
  5. Jeff KingDec 3, 2014
  6. Jeff KingDec 4, 2014
  7. Junio C HamanoDec 4, 2014
  8. Junio C HamanoDec 3, 2014
  9. brian m. carlsonDec 4, 2014
  10. 0/2 disabling terminal promptsJeff King, Dec 4, 2014
  11. 1/2 credential: let helpers tell us to quitJeff King, Dec 4, 2014
  12. 2/2 prompt: respect GIT_TERMINAL_PROMPT to disable terminal promptsJeff King, Dec 4, 2014
  13. Junio C HamanoDec 4, 2014
  14. Jeff KingDec 4, 2014
  15. Junio C HamanoDec 4, 2014
  16. Jeff KingDec 5, 2014
  17. Junio C HamanoDec 5, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.