diff options
author | brian m. carlson <bk2204@github.com> | 2020-02-20 02:24:13 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2020-02-20 13:05:43 -0800 |
commit | 46fd7b390034eb5dde6a3f955e677c5260e4d10c (patch) | |
tree | a35d6bf10ad09e279feca361865251072a04123f /credential.c | |
parent | 82eb249853868582d8ba65e3afc5a7dcaeb620ea (diff) | |
download | git-46fd7b390034eb5dde6a3f955e677c5260e4d10c.tar.gz |
credential: allow wildcard patterns when matching config
In some cases, a user will want to use a specific credential helper for
a wildcard pattern, such as https://*.corp.example.com. We have code
that handles this already with the urlmatch code, so let's use that
instead of our custom code.
Since the urlmatch code is a superset of our current matching in terms
of capabilities, there shouldn't be any cases of things that matched
previously that don't match now. However, in addition to wildcard
matching, we now use partial path matching, which can cause slightly
different behavior in the case that a helper applies to the prefix
(considering path components) of the remote URL. While different, this
is probably the behavior people were wanting anyway.
Since we're using the urlmatch code, we need to encode the components
we've gotten into a URL to match, so add a function to percent-encode
data and format the URL with it. We now also no longer need to the
custom code to match URLs, so let's remove it.
Additionally, the urlmatch code always looks for the best match, whereas
we want all matches for credential helpers to preserve existing
behavior. Let's add an optional field, select_fn, that lets us control
which items we want (in this case, all of them) and default it to the
best-match code that already exists for other users.
Signed-off-by: brian m. carlson <bk2204@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'credential.c')
-rw-r--r-- | credential.c | 66 |
1 files changed, 47 insertions, 19 deletions
diff --git a/credential.c b/credential.c index 5701e32792..77dfde44e3 100644 --- a/credential.c +++ b/credential.c @@ -6,6 +6,7 @@ #include "url.h" #include "prompt.h" #include "sigchain.h" +#include "urlmatch.h" void credential_init(struct credential *c) { @@ -40,7 +41,7 @@ static int credential_config_callback(const char *var, const char *value, void *data) { struct credential *c = data; - const char *key, *dot; + const char *key; if (!skip_prefix(var, "credential.", &key)) return 0; @@ -48,23 +49,6 @@ static int credential_config_callback(const char *var, const char *value, 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")) { if (*value) string_list_append(&c->helpers, value); @@ -89,11 +73,38 @@ static int proto_is_http(const char *s) return !strcmp(s, "https") || !strcmp(s, "http"); } +static void credential_describe(struct credential *c, struct strbuf *out); +static void credential_format(struct credential *c, struct strbuf *out); + +static int select_all(const struct urlmatch_item *a, + const struct urlmatch_item *b) +{ + return 0; +} + static void credential_apply_config(struct credential *c) { + char *normalized_url; + struct urlmatch_config config = { STRING_LIST_INIT_DUP }; + struct strbuf url = STRBUF_INIT; + if (c->configured) return; - git_config(credential_config_callback, c); + + config.section = "credential"; + config.key = NULL; + config.collect_fn = credential_config_callback; + config.cascade_fn = NULL; + config.select_fn = select_all; + config.cb = c; + + credential_format(c, &url); + normalized_url = url_normalize(url.buf, &config.url); + + git_config(urlmatch_config_entry, &config); + free(normalized_url); + strbuf_release(&url); + c->configured = 1; if (!c->use_http_path && proto_is_http(c->protocol)) { @@ -114,6 +125,23 @@ static void credential_describe(struct credential *c, struct strbuf *out) strbuf_addf(out, "/%s", c->path); } +static void credential_format(struct credential *c, struct strbuf *out) +{ + if (!c->protocol) + return; + strbuf_addf(out, "%s://", c->protocol); + if (c->username && *c->username) { + strbuf_add_percentencode(out, c->username); + strbuf_addch(out, '@'); + } + if (c->host) + strbuf_addstr(out, c->host); + if (c->path) { + strbuf_addch(out, '/'); + strbuf_add_percentencode(out, c->path); + } +} + static char *credential_ask_one(const char *what, struct credential *c, int flags) { |