Scenario: - There are a few pre-production systems that a lot of testers and developers need to time share because of low availability - Devops generates a GitHub token with pull only access and adds it to the netrc file on these systems (Pull only as we don't want testers/others to be able to push) - Testers log in and do a git pull for the latest changes (via netrc credentials - though testers may not be aware) - Developers login to debug issues and may make fixes to the test repo - Now when developers try to push their changes they receive: fatal: unable to access 'https://github.com/<org>/<project>/': The requested URL returned error: 403 - The developer is not given the chance to supply an authorized token and either needs to comment the netrc file or copy the changes over to their own machine
Signed-off-by: Ashlesh Gawande <git@ashlesh.me> --- http.c | 2 +- t/lib-httpd.sh | 9 +++++++++ t/lib-httpd/apache.conf | 4 ++++ t/lib-httpd/passwd | 1 + t/t5550-http-fetch-dumb.sh | 24 ++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-)
Show changes to 5 files +39 −1
http.c, t/lib-httpd.sh, t/lib-httpd/apache.conf, t/lib-httpd/passwd, t/t5550-http-fetch-dumb.sh
diff --git a/http.c b/http.c index 7e3af1e72f..18959f63b9 100644 --- a/http.c +++ b/http.c @@ -1852,7 +1852,7 @@ static int handle_curl_result(struct slot_results *results) return HTTP_NOMATCHPUBLICKEY; } else if (missing_target(results)) return HTTP_MISSING_TARGET; - else if (results->http_code == 401) { + else if (results->http_code == 401 || results->http_code == 403) { if ((http_auth.username && http_auth.password) ||\ (http_auth.authtype && http_auth.credential)) { if (http_auth.multistage) { diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 5091db949b..cdc92b2916 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -325,6 +325,15 @@ set_askpass() { echo "$2" >"$TRASH_DIRECTORY/askpass-pass" } +set_netrc() { + # $HOME=$TRASH_DIRECTORY + echo "machine $1 login $2 password $3" > $TRASH_DIRECTORY/.netrc +} + +clear_netrc() { + rm "$TRASH_DIRECTORY/.netrc" +} + expect_askpass() { dest=$HTTPD_DEST${3+/$3} diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index e631ab0eb5..6b8c50a51a 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -238,6 +238,10 @@ SSLEngine On AuthName "git-auth" AuthUserFile passwd Require valid-user + + # return 403 for authenticated user: forbidden-user@host + RewriteCond "%{REMOTE_USER}" "^forbidden-user@host" + RewriteRule ^ - [F] </Location> <LocationMatch "^/auth-push/.*/git-receive-pack$"> diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd index d9c122f348..3bab7b6423 100644 --- a/t/lib-httpd/passwd +++ b/t/lib-httpd/passwd @@ -1 +1,2 @@ user@host:$apr1$LGPmCZWj$9vxEwj5Z5GzQLBMxp3mCx1 +forbidden-user@host:$apr1$LGPmCZWj$9vxEwj5Z5GzQLBMxp3mCx1 diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index ed0ad66fad..6c4c1cafb2 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -102,6 +102,30 @@ test_expect_success 'cloning password-protected repository can fail' ' expect_askpass both wrong ' +test_expect_success 'using credentials from netrc to clone successfully' ' + set_askpass wrong && + set_netrc 127.0.0.1 user@host pass@host && + git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-netrc && + expect_askpass none +' +clear_netrc + +test_expect_success 'netrc unauthorized credentials (prompt after 401)' ' + set_askpass wrong && + set_netrc 127.0.0.1 user@host pass@wrong && + test_must_fail git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-netrc-401 && + expect_askpass both wrong +' +clear_netrc + +test_expect_success 'netrc authorized but forbidden credentials (prompt after 403)' ' + set_askpass wrong && + set_netrc 127.0.0.1 forbidden-user@host pass@host && + test_must_fail git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-netc-403 && + expect_askpass both wrong +' +clear_netrc + test_expect_success 'http auth can use user/pass in URL' ' set_askpass wrong && git clone "$HTTPD_URL_USER_PASS/auth/dumb/repo.git" clone-auth-none &&
-- 2.43.0