diff options
Diffstat (limited to 'credential.c')
-rw-r--r-- | credential.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/credential.c b/credential.c index c349b9aac3..96be1c22dd 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"); |