look for credentials in config before prompting

When an http request receives a 401, we ask the user for
both a username and password. While it's generally not a
good idea for us to store the password in plaintext, having
to input the username each time is annoying, and can be
easily solved with a config variable.

This patch teaches the credential subsystem to look up items
in the git config file before prompting. Items are indexed
by the "unique" token passed to the credential system.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King
2011-07-18 03:51:08 -04:00
committed by Junio C Hamano
parent 41b8701903
commit 20a93d32fa
4 changed files with 57 additions and 0 deletions

View File

@@ -4,6 +4,43 @@
#include "string-list.h"
#include "run-command.h"
static int credential_config_callback(const char *var, const char *value,
void *data)
{
struct credential *c = data;
if (!value)
return 0;
var = skip_prefix(var, "credential.");
if (!var)
return 0;
var = skip_prefix(var, c->unique);
if (!var)
return 0;
if (*var != '.')
return 0;
var++;
if (!strcmp(var, "username")) {
if (!c->username)
c->username = xstrdup(value);
}
else if (!strcmp(var, "password")) {
free(c->password);
c->password = xstrdup(value);
}
return 0;
}
void credential_from_config(struct credential *c)
{
if (c->unique)
git_config(credential_config_callback, c);
}
static char *credential_ask_one(const char *what, const char *desc)
{
struct strbuf prompt = STRBUF_INIT;
@@ -26,6 +63,7 @@ static char *credential_ask_one(const char *what, const char *desc)
int credential_getpass(struct credential *c)
{
credential_from_config(c);
if (!c->username)
c->username = credential_ask_one("Username", c->description);

View File

@@ -11,6 +11,7 @@ struct credential {
struct string_list;
int credential_getpass(struct credential *);
void credential_from_config(struct credential *);
int credential_fill_gently(struct credential *, const struct string_list *methods);
void credential_fill(struct credential *, const struct string_list *methods);

View File

@@ -172,4 +172,14 @@ test_expect_success 'internal getpass does not ask for known username' '
EOF
'
test_expect_success 'internal getpass can pull from config' '
git config credential.foo.username configured-username
check --unique=foo <<-\EOF
username=configured-username
password=askpass-result
--
askpass: Password:
EOF
'
test_done

View File

@@ -85,6 +85,14 @@ test_expect_success 'http auth can request both user and pass' '
test_cmp askpass-expect-both askpass-query
'
test_expect_success 'http auth can pull user from config' '
>askpass-query &&
echo user@host >askpass-response &&
git config --global credential.$HTTPD_PROTO:$HTTPD_DEST.username user@host &&
git clone "$HTTPD_URL/auth/repo.git" clone-auth-config &&
test_cmp askpass-expect-pass askpass-query
'
test_expect_success 'fetch changes via http' '
echo content >>file &&
git commit -a -m two &&