| #!/bin/sh | |
| # Try a set of credential helpers; the expected stdin, | |
| # stdout and stderr should be provided on stdin, | |
| # separated by "--". | |
| check() { | |
| credential_opts= | |
| credential_cmd=$1 | |
| shift | |
| for arg in "$@"; do | |
| credential_opts="$credential_opts -c credential.helper='$arg'" | |
| done | |
| read_chunk >stdin && | |
| read_chunk >expect-stdout && | |
| read_chunk >expect-stderr && | |
| if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then | |
| echo "git credential failed with code $?" && | |
| cat stderr && | |
| false | |
| fi && | |
| test_cmp expect-stdout stdout && | |
| test_cmp expect-stderr stderr | |
| } | |
| read_chunk() { | |
| while read line; do | |
| case "$line" in | |
| --) break ;; | |
| *) echo "$line" ;; | |
| esac | |
| done | |
| } | |
| # Clear any residual data from previous tests. We only | |
| # need this when testing third-party helpers which read and | |
| # write outside of our trash-directory sandbox. | |
| # | |
| # Don't bother checking for success here, as it is | |
| # outside the scope of tests and represents a best effort to | |
| # clean up after ourselves. | |
| helper_test_clean() { | |
| reject $1 https example.com store-user | |
| reject $1 https example.com user1 | |
| reject $1 https example.com user2 | |
| reject $1 http path.tld user | |
| reject $1 https timeout.tld user | |
| reject $1 https sso.tld | |
| } | |
| reject() { | |
| ( | |
| echo protocol=$2 | |
| echo host=$3 | |
| echo username=$4 | |
| ) | git -c credential.helper=$1 credential reject | |
| } | |
| helper_test() { | |
| HELPER=$1 | |
| test_expect_success "helper ($HELPER) has no existing data" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''https://example.com'\'': | |
| askpass: Password for '\''https://askpass-username@example.com'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) stores password" ' | |
| check approve $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| username=store-user | |
| password=store-pass | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) can retrieve password" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=store-user | |
| password=store-pass | |
| -- | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) requires matching protocol" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=http | |
| host=example.com | |
| -- | |
| protocol=http | |
| host=example.com | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''http://example.com'\'': | |
| askpass: Password for '\''http://askpass-username@example.com'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) requires matching host" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=other.tld | |
| -- | |
| protocol=https | |
| host=other.tld | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''https://other.tld'\'': | |
| askpass: Password for '\''https://askpass-username@other.tld'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) requires matching username" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| username=other | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=other | |
| password=askpass-password | |
| -- | |
| askpass: Password for '\''https://other@example.com'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) requires matching path" ' | |
| test_config credential.usehttppath true && | |
| check approve $HELPER <<-\EOF && | |
| protocol=http | |
| host=path.tld | |
| path=foo.git | |
| username=user | |
| password=pass | |
| EOF | |
| check fill $HELPER <<-\EOF | |
| protocol=http | |
| host=path.tld | |
| path=bar.git | |
| -- | |
| protocol=http | |
| host=path.tld | |
| path=bar.git | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''http://path.tld/bar.git'\'': | |
| askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) can forget host" ' | |
| check reject $HELPER <<-\EOF && | |
| protocol=https | |
| host=example.com | |
| EOF | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''https://example.com'\'': | |
| askpass: Password for '\''https://askpass-username@example.com'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) can store multiple users" ' | |
| check approve $HELPER <<-\EOF && | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| password=pass1 | |
| EOF | |
| check approve $HELPER <<-\EOF && | |
| protocol=https | |
| host=example.com | |
| username=user2 | |
| password=pass2 | |
| EOF | |
| check fill $HELPER <<-\EOF && | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| password=pass1 | |
| EOF | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| username=user2 | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=user2 | |
| password=pass2 | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) can forget user" ' | |
| check reject $HELPER <<-\EOF && | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| EOF | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=user1 | |
| password=askpass-password | |
| -- | |
| askpass: Password for '\''https://user1@example.com'\'': | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) remembers other user" ' | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=example.com | |
| username=user2 | |
| -- | |
| protocol=https | |
| host=example.com | |
| username=user2 | |
| password=pass2 | |
| EOF | |
| ' | |
| test_expect_success "helper ($HELPER) can store empty username" ' | |
| check approve $HELPER <<-\EOF && | |
| protocol=https | |
| host=sso.tld | |
| username= | |
| password= | |
| EOF | |
| check fill $HELPER <<-\EOF | |
| protocol=https | |
| host=sso.tld | |
| -- | |
| protocol=https | |
| host=sso.tld | |
| username= | |
| password= | |
| EOF | |
| ' | |
| } | |
| helper_test_timeout() { | |
| HELPER="$*" | |
| test_expect_success "helper ($HELPER) times out" ' | |
| check approve "$HELPER" <<-\EOF && | |
| protocol=https | |
| host=timeout.tld | |
| username=user | |
| password=pass | |
| EOF | |
| sleep 2 && | |
| check fill "$HELPER" <<-\EOF | |
| protocol=https | |
| host=timeout.tld | |
| -- | |
| protocol=https | |
| host=timeout.tld | |
| username=askpass-username | |
| password=askpass-password | |
| -- | |
| askpass: Username for '\''https://timeout.tld'\'': | |
| askpass: Password for '\''https://askpass-username@timeout.tld'\'': | |
| EOF | |
| ' | |
| } | |
| write_script askpass <<\EOF | |
| echo >&2 askpass: $* | |
| what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z) | |
| echo "askpass-$what" | |
| EOF | |
| GIT_ASKPASS="$PWD/askpass" | |
| export GIT_ASKPASS |