From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCHv2 06/13] credential: apply helper config
Date: Tue, 6 Dec 2011 01:22:47 -0500 [thread overview]
Message-ID: <20111206062247.GF29233@sigill.intra.peff.net> (raw)
In-Reply-To: <20111206062127.GA29046@sigill.intra.peff.net>
The functionality for credential storage helpers is already
there; we just need to give the users a way to turn it on.
This patch provides a "credential.helper" configuration
variable which allows the user to provide one or more helper
strings.
Rather than simply matching credential.helper, we will also
compare URLs in subsection headings to the current context.
This means you can apply configuration to a subset of
credentials. For example:
[credential "https://example.com"]
helper = foo
would match a request for "https://example.com/foo.git", but
not one for "https://kernel.org/foo.git".
This is overkill for the "helper" variable, since users are
unlikely to want different helpers for different sites (and
since helpers run arbitrary code, they could do the matching
themselves anyway).
However, future patches will add new config variables where
this extra feature will be more useful.
Signed-off-by: Jeff King <peff@peff.net>
---
credential.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
credential.h | 5 +++-
t/t0300-credentials.sh | 42 +++++++++++++++++++++++++++++++++
t/t5550-http-fetch.sh | 12 +++++++++
4 files changed, 119 insertions(+), 1 deletions(-)
diff --git a/credential.c b/credential.c
index c349b9a..96be1c2 100644
--- a/credential.c
+++ b/credential.c
@@ -22,6 +22,61 @@ void credential_clear(struct credential *c)
credential_init(c);
}
+int credential_match(const struct credential *want,
+ const struct credential *have)
+{
+#define CHECK(x) (!want->x || (have->x && !strcmp(want->x, have->x)))
+ return CHECK(protocol) &&
+ CHECK(host) &&
+ CHECK(path) &&
+ CHECK(username);
+#undef CHECK
+}
+
+static int credential_config_callback(const char *var, const char *value,
+ void *data)
+{
+ struct credential *c = data;
+ const char *key, *dot;
+
+ key = skip_prefix(var, "credential.");
+ if (!key)
+ return 0;
+
+ if (!value)
+ return config_error_nonbool(var);
+
+ dot = strrchr(key, '.');
+ if (dot) {
+ struct credential want = CREDENTIAL_INIT;
+ char *url = xmemdupz(key, dot - key);
+ int matched;
+
+ credential_from_url(&want, url);
+ matched = credential_match(&want, c);
+
+ credential_clear(&want);
+ free(url);
+
+ if (!matched)
+ return 0;
+ key = dot + 1;
+ }
+
+ if (!strcmp(key, "helper"))
+ string_list_append(&c->helpers, value);
+
+ return 0;
+}
+
+static void credential_apply_config(struct credential *c)
+{
+ if (c->configured)
+ return;
+ git_config(credential_config_callback, c);
+ c->configured = 1;
+}
+
static void credential_describe(struct credential *c, struct strbuf *out)
{
if (!c->protocol)
@@ -195,6 +250,8 @@ void credential_fill(struct credential *c)
if (c->username && c->password)
return;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++) {
credential_do(c, c->helpers.items[i].string, "get");
if (c->username && c->password)
@@ -215,6 +272,8 @@ void credential_approve(struct credential *c)
if (!c->username || !c->password)
return;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++)
credential_do(c, c->helpers.items[i].string, "store");
c->approved = 1;
@@ -224,6 +283,8 @@ void credential_reject(struct credential *c)
{
int i;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++)
credential_do(c, c->helpers.items[i].string, "erase");
diff --git a/credential.h b/credential.h
index 8a6d162..e504272 100644
--- a/credential.h
+++ b/credential.h
@@ -5,7 +5,8 @@
struct credential {
struct string_list helpers;
- unsigned approved:1;
+ unsigned approved:1,
+ configured:1;
char *username;
char *password;
@@ -25,5 +26,7 @@ struct credential {
int credential_read(struct credential *, FILE *);
void credential_from_url(struct credential *, const char *url);
+int credential_match(const struct credential *have,
+ const struct credential *want);
#endif /* CREDENTIAL_H */
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 81a455f..e3f61f4 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -192,4 +192,46 @@ test_expect_success 'internal getpass does not ask for known username' '
EOF
'
+HELPER="f() {
+ cat >/dev/null
+ echo username=foo
+ echo password=bar
+ }; f"
+test_expect_success 'respect configured credentials' '
+ test_config credential.helper "$HELPER" &&
+ check fill <<-\EOF
+ --
+ username=foo
+ password=bar
+ --
+ EOF
+'
+
+test_expect_success 'match configured credential' '
+ test_config credential.https://example.com.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=example.com
+ path=repo.git
+ --
+ username=foo
+ password=bar
+ --
+ EOF
+'
+
+test_expect_success 'do not match configured credential' '
+ test_config credential.https://foo.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=bar
+ --
+ username=askpass-username
+ password=askpass-password
+ --
+ askpass: Username for '\''https://bar'\'':
+ askpass: Password for '\''https://askpass-username@bar'\'':
+ EOF
+'
+
test_done
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index 398a2d2..21e2f5d 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -101,6 +101,18 @@ test_expect_success 'http auth can request both user and pass' '
expect_askpass both user@host
'
+test_expect_success 'http auth respects credential helper config' '
+ test_config_global credential.helper "f() {
+ cat >/dev/null
+ echo username=user@host
+ echo password=user@host
+ }; f" &&
+ >askpass-query &&
+ echo wrong >askpass-response &&
+ git clone "$HTTPD_URL/auth/repo.git" clone-auth-helper &&
+ expect_askpass none
+'
+
test_expect_success 'fetch changes via http' '
echo content >>file &&
git commit -a -m two &&
--
1.7.8.rc4.4.g884ec
next prev parent reply other threads:[~2011-12-06 6:23 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-06 6:21 [PATCHv2 0/13] credential helpers Jeff King
2011-12-06 6:22 ` [PATCHv2 01/13] test-lib: add test_config_global variant Jeff King
2011-12-06 6:22 ` [PATCHv2 02/13] t5550: fix typo Jeff King
2011-12-06 6:22 ` [PATCHv2 03/13] introduce credentials API Jeff King
2011-12-06 6:22 ` [PATCHv2 04/13] credential: add function for parsing url components Jeff King
2011-12-06 6:22 ` [PATCHv2 05/13] http: use credential API to get passwords Jeff King
2011-12-06 6:22 ` Jeff King [this message]
2011-12-06 23:58 ` [PATCHv2 06/13] credential: apply helper config Junio C Hamano
2011-12-07 0:45 ` Jeff King
2011-12-07 0:49 ` Jeff King
2011-12-06 6:22 ` [PATCHv2 07/13] credential: add credential.*.username Jeff King
2011-12-06 6:22 ` [PATCHv2 08/13] credential: make relevance of http path configurable Jeff King
2011-12-06 6:22 ` [PATCHv2 09/13] docs: end-user documentation for the credential subsystem Jeff King
2011-12-06 6:22 ` [PATCHv2 10/13] credentials: add "cache" helper Jeff King
2011-12-06 6:23 ` [PATCHv2 11/13] strbuf: add strbuf_add*_urlencode Jeff King
2011-12-06 6:23 ` [PATCHv2 12/13] credentials: add "store" helper Jeff King
2011-12-06 21:50 ` Junio C Hamano
2011-12-09 23:19 ` Jeff King
2011-12-06 6:23 ` [PATCHv2 13/13] t: add test harness for external credential helpers Jeff King
2011-12-06 21:51 ` Junio C Hamano
2011-12-06 22:08 ` Jeff King
2011-12-06 21:40 ` [PATCHv2 0/13] " Junio C Hamano
2011-12-07 6:42 ` Jeff King
2011-12-08 21:34 ` Junio C Hamano
2011-12-09 2:29 ` Jeff King
2011-12-09 18:00 ` Junio C Hamano
2011-12-09 23:18 ` Jeff King
2011-12-09 23:34 ` Junio C Hamano
2011-12-09 23:39 ` Jeff King
2011-12-09 23:56 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111206062247.GF29233@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).