diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-05-10 10:23:28 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-05-10 10:23:29 -0700 |
commit | 2ca91d1ee07f934fa7f57ba34c397b150eef023f (patch) | |
tree | d71bd150edc85eedc736f64e896acad327874343 | |
parent | c05615e1c5876bea3c35202771d3db83b3336437 (diff) | |
parent | a5c76569e798ad3656afe6b67f37cbbb2e47f28c (diff) | |
download | git-2ca91d1ee07f934fa7f57ba34c397b150eef023f.tar.gz |
Merge branch 'mh/credential-oauth-refresh-token'
The credential subsystem learns to help OAuth framework.
* mh/credential-oauth-refresh-token:
credential: new attribute oauth_refresh_token
-rw-r--r-- | Documentation/git-credential.txt | 6 | ||||
-rw-r--r-- | builtin/credential-cache--daemon.c | 3 | ||||
-rw-r--r-- | credential.c | 6 | ||||
-rw-r--r-- | credential.h | 1 | ||||
-rw-r--r-- | t/lib-credential.sh | 30 | ||||
-rwxr-xr-x | t/t0300-credentials.sh | 18 | ||||
-rwxr-xr-x | t/t0301-credential-cache.sh | 1 |
7 files changed, 65 insertions, 0 deletions
diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt index 3394c03611..0e6d9e85ec 100644 --- a/Documentation/git-credential.txt +++ b/Documentation/git-credential.txt @@ -156,6 +156,12 @@ Git understands the following attributes: When reading credentials from helpers, `git credential fill` ignores expired passwords. Represented as Unix time UTC, seconds since 1970. +`oauth_refresh_token`:: + + An OAuth refresh token may accompany a password that is an OAuth access + token. Helpers must treat this attribute as confidential like the password + attribute. Git itself has no special behaviour for this attribute. + `url`:: When this special attribute is read by `git credential`, the diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 4e571d9951..756c5f02ae 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -134,6 +134,9 @@ static void serve_one_client(FILE *in, FILE *out) if (e->item.password_expiry_utc != TIME_MAX) fprintf(out, "password_expiry_utc=%"PRItime"\n", e->item.password_expiry_utc); + if (e->item.oauth_refresh_token) + fprintf(out, "oauth_refresh_token=%s\n", + e->item.oauth_refresh_token); } } else if (!strcmp(action.buf, "exit")) { diff --git a/credential.c b/credential.c index 7da326aa85..023b59d571 100644 --- a/credential.c +++ b/credential.c @@ -25,6 +25,7 @@ void credential_clear(struct credential *c) free(c->path); free(c->username); free(c->password); + free(c->oauth_refresh_token); string_list_clear(&c->helpers, 0); strvec_clear(&c->wwwauth_headers); @@ -246,6 +247,9 @@ int credential_read(struct credential *c, FILE *fp) c->password_expiry_utc = parse_timestamp(value, NULL, 10); if (c->password_expiry_utc == 0 || errno == ERANGE) c->password_expiry_utc = TIME_MAX; + } else if (!strcmp(key, "oauth_refresh_token")) { + free(c->oauth_refresh_token); + c->oauth_refresh_token = xstrdup(value); } else if (!strcmp(key, "url")) { credential_from_url(c, value); } else if (!strcmp(key, "quit")) { @@ -281,6 +285,7 @@ void credential_write(const struct credential *c, FILE *fp) credential_write_item(fp, "path", c->path, 0); credential_write_item(fp, "username", c->username, 0); credential_write_item(fp, "password", c->password, 0); + credential_write_item(fp, "oauth_refresh_token", c->oauth_refresh_token, 0); if (c->password_expiry_utc != TIME_MAX) { char *s = xstrfmt("%"PRItime, c->password_expiry_utc); credential_write_item(fp, "password_expiry_utc", s, 0); @@ -406,6 +411,7 @@ void credential_reject(struct credential *c) FREE_AND_NULL(c->username); FREE_AND_NULL(c->password); + FREE_AND_NULL(c->oauth_refresh_token); c->password_expiry_utc = TIME_MAX; c->approved = 0; } diff --git a/credential.h b/credential.h index 2b5958cd43..b8e2936d1d 100644 --- a/credential.h +++ b/credential.h @@ -141,6 +141,7 @@ struct credential { char *protocol; char *host; char *path; + char *oauth_refresh_token; timestamp_t password_expiry_utc; }; diff --git a/t/lib-credential.sh b/t/lib-credential.sh index d7d03c3cd9..f1ab92ba35 100644 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -43,6 +43,7 @@ helper_test_clean() { reject $1 https example.com store-user reject $1 https example.com user1 reject $1 https example.com user2 + reject $1 https example.com user4 reject $1 http path.tld user reject $1 https timeout.tld user reject $1 https sso.tld @@ -327,6 +328,35 @@ helper_test_timeout() { ' } +helper_test_oauth_refresh_token() { + HELPER=$1 + + test_expect_success "helper ($HELPER) stores oauth_refresh_token" ' + check approve $HELPER <<-\EOF + protocol=https + host=example.com + username=user4 + password=pass + oauth_refresh_token=xyzzy + EOF + ' + + test_expect_success "helper ($HELPER) gets oauth_refresh_token" ' + check fill $HELPER <<-\EOF + protocol=https + host=example.com + username=user4 + -- + protocol=https + host=example.com + username=user4 + password=pass + oauth_refresh_token=xyzzy + -- + EOF + ' +} + write_script askpass <<\EOF echo >&2 askpass: $* what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z) diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh index b8612ede95..a4f5bba507 100755 --- a/t/t0300-credentials.sh +++ b/t/t0300-credentials.sh @@ -214,6 +214,24 @@ test_expect_success 'credential_approve stores password expiry' ' EOF ' +test_expect_success 'credential_approve stores oauth refresh token' ' + check approve useless <<-\EOF + protocol=http + host=example.com + username=foo + password=bar + oauth_refresh_token=xyzzy + -- + -- + useless: store + useless: protocol=http + useless: host=example.com + useless: username=foo + useless: password=bar + useless: oauth_refresh_token=xyzzy + EOF +' + test_expect_success 'do not bother storing password-less credential' ' check approve useless <<-\EOF protocol=http diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh index 698b7159f0..c02a3b5969 100755 --- a/t/t0301-credential-cache.sh +++ b/t/t0301-credential-cache.sh @@ -29,6 +29,7 @@ test_atexit 'git credential-cache exit' # test that the daemon works with no special setup helper_test cache +helper_test_oauth_refresh_token cache test_expect_success 'socket defaults to ~/.cache/git/credential/socket' ' test_when_finished " |