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 username=askpass-username
66 password=askpass-password
67 --
68 askpass: Username for '\''https://example.com'\'':
69 askpass: Password for '\''https://askpass-username@example.com'\'':
70 EOF
71 '
72
73 test_expect_success "helper ($HELPER) stores password" '
74 check approve $HELPER <<-\EOF
75 protocol=https
76 host=example.com
77 username=store-user
78 password=store-pass
79 EOF
80 '
81
82 test_expect_success "helper ($HELPER) can retrieve password" '
83 check fill $HELPER <<-\EOF
84 protocol=https
85 host=example.com
86 --
87 username=store-user
88 password=store-pass
89 --
90 EOF
91 '
92
93 test_expect_success "helper ($HELPER) requires matching protocol" '
94 check fill $HELPER <<-\EOF
95 protocol=http
96 host=example.com
97 --
98 username=askpass-username
99 password=askpass-password
100 --
101 askpass: Username for '\''http://example.com'\'':
102 askpass: Password for '\''http://askpass-username@example.com'\'':
103 EOF
104 '
105
106 test_expect_success "helper ($HELPER) requires matching host" '
107 check fill $HELPER <<-\EOF
108 protocol=https
109 host=other.tld
110 --
111 username=askpass-username
112 password=askpass-password
113 --
114 askpass: Username for '\''https://other.tld'\'':
115 askpass: Password for '\''https://askpass-username@other.tld'\'':
116 EOF
117 '
118
119 test_expect_success "helper ($HELPER) requires matching username" '
120 check fill $HELPER <<-\EOF
121 protocol=https
122 host=example.com
123 username=other
124 --
125 username=other
126 password=askpass-password
127 --
128 askpass: Password for '\''https://other@example.com'\'':
129 EOF
130 '
131
132 test_expect_success "helper ($HELPER) requires matching path" '
133 test_config credential.usehttppath true &&
134 check approve $HELPER <<-\EOF &&
135 protocol=http
136 host=path.tld
137 path=foo.git
138 username=user
139 password=pass
140 EOF
141 check fill $HELPER <<-\EOF
142 protocol=http
143 host=path.tld
144 path=bar.git
145 --
146 username=askpass-username
147 password=askpass-password
148 --
149 askpass: Username for '\''http://path.tld/bar.git'\'':
150 askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
151 EOF
152 '
153
154 test_expect_success "helper ($HELPER) can forget host" '
155 check reject $HELPER <<-\EOF &&
156 protocol=https
157 host=example.com
158 EOF
159 check fill $HELPER <<-\EOF
160 protocol=https
161 host=example.com
162 --
163 username=askpass-username
164 password=askpass-password
165 --
166 askpass: Username for '\''https://example.com'\'':
167 askpass: Password for '\''https://askpass-username@example.com'\'':
168 EOF
169 '
170
171 test_expect_success "helper ($HELPER) can store multiple users" '
172 check approve $HELPER <<-\EOF &&
173 protocol=https
174 host=example.com
175 username=user1
176 password=pass1
177 EOF
178 check approve $HELPER <<-\EOF &&
179 protocol=https
180 host=example.com
181 username=user2
182 password=pass2
183 EOF
184 check fill $HELPER <<-\EOF &&
185 protocol=https
186 host=example.com
187 username=user1
188 --
189 username=user1
190 password=pass1
191 EOF
192 check fill $HELPER <<-\EOF
193 protocol=https
194 host=example.com
195 username=user2
196 --
197 username=user2
198 password=pass2
199 EOF
200 '
201
202 test_expect_success "helper ($HELPER) can forget user" '
203 check reject $HELPER <<-\EOF &&
204 protocol=https
205 host=example.com
206 username=user1
207 EOF
208 check fill $HELPER <<-\EOF
209 protocol=https
210 host=example.com
211 username=user1
212 --
213 username=user1
214 password=askpass-password
215 --
216 askpass: Password for '\''https://user1@example.com'\'':
217 EOF
218 '
219
220 test_expect_success "helper ($HELPER) remembers other user" '
221 check fill $HELPER <<-\EOF
222 protocol=https
223 host=example.com
224 username=user2
225 --
226 username=user2
227 password=pass2
228 EOF
229 '
230}
231
232helper_test_timeout() {
233 HELPER="$*"
234
235 test_expect_success "helper ($HELPER) times out" '
236 check approve "$HELPER" <<-\EOF &&
237 protocol=https
238 host=timeout.tld
239 username=user
240 password=pass
241 EOF
242 sleep 2 &&
243 check fill "$HELPER" <<-\EOF
244 protocol=https
245 host=timeout.tld
246 --
247 username=askpass-username
248 password=askpass-password
249 --
250 askpass: Username for '\''https://timeout.tld'\'':
251 askpass: Password for '\''https://askpass-username@timeout.tld'\'':
252 EOF
253 '
254}
255
256cat >askpass <<\EOF
257#!/bin/sh
258echo >&2 askpass: $*
259what=`echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z`
260echo "askpass-$what"
261EOF
262chmod +x askpass
263GIT_ASKPASS="$PWD/askpass"
264export GIT_ASKPASS