t / lib-credential.shon commit Merge branch 'ss/fix-config-fd-leak' into maint (8136099)
   1#!/bin/sh
   2
   3# Try a set of credential helpers; the expected stdin,
   4# stdout and stderr should be provided on stdin,
   5# separated by "--".
   6check() {
   7        credential_opts=
   8        credential_cmd=$1
   9        shift
  10        for arg in "$@"; do
  11                credential_opts="$credential_opts -c credential.helper='$arg'"
  12        done
  13        read_chunk >stdin &&
  14        read_chunk >expect-stdout &&
  15        read_chunk >expect-stderr &&
  16        if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
  17                echo "git credential failed with code $?" &&
  18                cat stderr &&
  19                false
  20        fi &&
  21        test_cmp expect-stdout stdout &&
  22        test_cmp expect-stderr stderr
  23}
  24
  25read_chunk() {
  26        while read line; do
  27                case "$line" in
  28                --) break ;;
  29                *) echo "$line" ;;
  30                esac
  31        done
  32}
  33
  34# Clear any residual data from previous tests. We only
  35# need this when testing third-party helpers which read and
  36# write outside of our trash-directory sandbox.
  37#
  38# Don't bother checking for success here, as it is
  39# outside the scope of tests and represents a best effort to
  40# clean up after ourselves.
  41helper_test_clean() {
  42        reject $1 https example.com store-user
  43        reject $1 https example.com user1
  44        reject $1 https example.com user2
  45        reject $1 http path.tld user
  46        reject $1 https timeout.tld user
  47}
  48
  49reject() {
  50        (
  51                echo protocol=$2
  52                echo host=$3
  53                echo username=$4
  54        ) | git -c credential.helper=$1 credential reject
  55}
  56
  57helper_test() {
  58        HELPER=$1
  59
  60        test_expect_success "helper ($HELPER) has no existing data" '
  61                check fill $HELPER <<-\EOF
  62                protocol=https
  63                host=example.com
  64                --
  65                protocol=https
  66                host=example.com
  67                username=askpass-username
  68                password=askpass-password
  69                --
  70                askpass: Username for '\''https://example.com'\'':
  71                askpass: Password for '\''https://askpass-username@example.com'\'':
  72                EOF
  73        '
  74
  75        test_expect_success "helper ($HELPER) stores password" '
  76                check approve $HELPER <<-\EOF
  77                protocol=https
  78                host=example.com
  79                username=store-user
  80                password=store-pass
  81                EOF
  82        '
  83
  84        test_expect_success "helper ($HELPER) can retrieve password" '
  85                check fill $HELPER <<-\EOF
  86                protocol=https
  87                host=example.com
  88                --
  89                protocol=https
  90                host=example.com
  91                username=store-user
  92                password=store-pass
  93                --
  94                EOF
  95        '
  96
  97        test_expect_success "helper ($HELPER) requires matching protocol" '
  98                check fill $HELPER <<-\EOF
  99                protocol=http
 100                host=example.com
 101                --
 102                protocol=http
 103                host=example.com
 104                username=askpass-username
 105                password=askpass-password
 106                --
 107                askpass: Username for '\''http://example.com'\'':
 108                askpass: Password for '\''http://askpass-username@example.com'\'':
 109                EOF
 110        '
 111
 112        test_expect_success "helper ($HELPER) requires matching host" '
 113                check fill $HELPER <<-\EOF
 114                protocol=https
 115                host=other.tld
 116                --
 117                protocol=https
 118                host=other.tld
 119                username=askpass-username
 120                password=askpass-password
 121                --
 122                askpass: Username for '\''https://other.tld'\'':
 123                askpass: Password for '\''https://askpass-username@other.tld'\'':
 124                EOF
 125        '
 126
 127        test_expect_success "helper ($HELPER) requires matching username" '
 128                check fill $HELPER <<-\EOF
 129                protocol=https
 130                host=example.com
 131                username=other
 132                --
 133                protocol=https
 134                host=example.com
 135                username=other
 136                password=askpass-password
 137                --
 138                askpass: Password for '\''https://other@example.com'\'':
 139                EOF
 140        '
 141
 142        test_expect_success "helper ($HELPER) requires matching path" '
 143                test_config credential.usehttppath true &&
 144                check approve $HELPER <<-\EOF &&
 145                protocol=http
 146                host=path.tld
 147                path=foo.git
 148                username=user
 149                password=pass
 150                EOF
 151                check fill $HELPER <<-\EOF
 152                protocol=http
 153                host=path.tld
 154                path=bar.git
 155                --
 156                protocol=http
 157                host=path.tld
 158                path=bar.git
 159                username=askpass-username
 160                password=askpass-password
 161                --
 162                askpass: Username for '\''http://path.tld/bar.git'\'':
 163                askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
 164                EOF
 165        '
 166
 167        test_expect_success "helper ($HELPER) can forget host" '
 168                check reject $HELPER <<-\EOF &&
 169                protocol=https
 170                host=example.com
 171                EOF
 172                check fill $HELPER <<-\EOF
 173                protocol=https
 174                host=example.com
 175                --
 176                protocol=https
 177                host=example.com
 178                username=askpass-username
 179                password=askpass-password
 180                --
 181                askpass: Username for '\''https://example.com'\'':
 182                askpass: Password for '\''https://askpass-username@example.com'\'':
 183                EOF
 184        '
 185
 186        test_expect_success "helper ($HELPER) can store multiple users" '
 187                check approve $HELPER <<-\EOF &&
 188                protocol=https
 189                host=example.com
 190                username=user1
 191                password=pass1
 192                EOF
 193                check approve $HELPER <<-\EOF &&
 194                protocol=https
 195                host=example.com
 196                username=user2
 197                password=pass2
 198                EOF
 199                check fill $HELPER <<-\EOF &&
 200                protocol=https
 201                host=example.com
 202                username=user1
 203                --
 204                protocol=https
 205                host=example.com
 206                username=user1
 207                password=pass1
 208                EOF
 209                check fill $HELPER <<-\EOF
 210                protocol=https
 211                host=example.com
 212                username=user2
 213                --
 214                protocol=https
 215                host=example.com
 216                username=user2
 217                password=pass2
 218                EOF
 219        '
 220
 221        test_expect_success "helper ($HELPER) can forget user" '
 222                check reject $HELPER <<-\EOF &&
 223                protocol=https
 224                host=example.com
 225                username=user1
 226                EOF
 227                check fill $HELPER <<-\EOF
 228                protocol=https
 229                host=example.com
 230                username=user1
 231                --
 232                protocol=https
 233                host=example.com
 234                username=user1
 235                password=askpass-password
 236                --
 237                askpass: Password for '\''https://user1@example.com'\'':
 238                EOF
 239        '
 240
 241        test_expect_success "helper ($HELPER) remembers other user" '
 242                check fill $HELPER <<-\EOF
 243                protocol=https
 244                host=example.com
 245                username=user2
 246                --
 247                protocol=https
 248                host=example.com
 249                username=user2
 250                password=pass2
 251                EOF
 252        '
 253}
 254
 255helper_test_timeout() {
 256        HELPER="$*"
 257
 258        test_expect_success "helper ($HELPER) times out" '
 259                check approve "$HELPER" <<-\EOF &&
 260                protocol=https
 261                host=timeout.tld
 262                username=user
 263                password=pass
 264                EOF
 265                sleep 2 &&
 266                check fill "$HELPER" <<-\EOF
 267                protocol=https
 268                host=timeout.tld
 269                --
 270                protocol=https
 271                host=timeout.tld
 272                username=askpass-username
 273                password=askpass-password
 274                --
 275                askpass: Username for '\''https://timeout.tld'\'':
 276                askpass: Password for '\''https://askpass-username@timeout.tld'\'':
 277                EOF
 278        '
 279}
 280
 281write_script askpass <<\EOF
 282echo >&2 askpass: $*
 283what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
 284echo "askpass-$what"
 285EOF
 286GIT_ASKPASS="$PWD/askpass"
 287export GIT_ASKPASS