Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
credential: let helpers tell us to quit
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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Dec 4, 2014
1 parent 7fa1365 commit 59b3865
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 1 deletion.
5 changes: 4 additions & 1 deletion Documentation/technical/api-credentials.txt
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions credential.c
Expand Up @@ -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
Expand Down Expand Up @@ -275,6 +277,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);
Expand Down
1 change: 1 addition & 0 deletions credential.h
Expand Up @@ -7,6 +7,7 @@ struct credential {
struct string_list helpers;
unsigned approved:1,
configured:1,
quit:1,
use_http_path:1;

char *username;
Expand Down
9 changes: 9 additions & 0 deletions t/t0300-credentials.sh
Expand Up @@ -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

0 comments on commit 59b3865

Please sign in to comment.