]>
Commit | Line | Data |
---|---|---|
f27491d5 JK |
1 | # Shell library for testing credential handling including helpers. See t0302 |
2 | # for an example of testing a specific helper. | |
abca927d JK |
3 | |
4 | # Try a set of credential helpers; the expected stdin, | |
5 | # stdout and stderr should be provided on stdin, | |
6 | # separated by "--". | |
7 | check() { | |
e30b2feb JRI |
8 | credential_opts= |
9 | credential_cmd=$1 | |
10 | shift | |
11 | for arg in "$@"; do | |
12 | credential_opts="$credential_opts -c credential.helper='$arg'" | |
13 | done | |
abca927d JK |
14 | read_chunk >stdin && |
15 | read_chunk >expect-stdout && | |
16 | read_chunk >expect-stderr && | |
e30b2feb JRI |
17 | if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then |
18 | echo "git credential failed with code $?" && | |
19 | cat stderr && | |
20 | false | |
21 | fi && | |
abca927d | 22 | test_cmp expect-stdout stdout && |
1108cea7 | 23 | test_cmp expect-stderr stderr |
abca927d JK |
24 | } |
25 | ||
26 | read_chunk() { | |
27 | while read line; do | |
28 | case "$line" in | |
29 | --) break ;; | |
30 | *) echo "$line" ;; | |
31 | esac | |
32 | done | |
33 | } | |
34 | ||
e2770979 JK |
35 | # Clear any residual data from previous tests. We only |
36 | # need this when testing third-party helpers which read and | |
37 | # write outside of our trash-directory sandbox. | |
38 | # | |
39 | # Don't bother checking for success here, as it is | |
40 | # outside the scope of tests and represents a best effort to | |
41 | # clean up after ourselves. | |
42 | helper_test_clean() { | |
43 | reject $1 https example.com store-user | |
44 | reject $1 https example.com user1 | |
45 | reject $1 https example.com user2 | |
a5c76569 | 46 | reject $1 https example.com user4 |
aeb21ce2 H |
47 | reject $1 https example.com user-distinct-pass |
48 | reject $1 https example.com user-overwrite | |
6c26da84 H |
49 | reject $1 https example.com user-erase1 |
50 | reject $1 https example.com user-erase2 | |
e2770979 JK |
51 | reject $1 http path.tld user |
52 | reject $1 https timeout.tld user | |
3c90bda6 | 53 | reject $1 https sso.tld |
e2770979 JK |
54 | } |
55 | ||
56 | reject() { | |
57 | ( | |
58 | echo protocol=$2 | |
59 | echo host=$3 | |
60 | echo username=$4 | |
e30b2feb | 61 | ) | git -c credential.helper=$1 credential reject |
e2770979 JK |
62 | } |
63 | ||
64 | helper_test() { | |
65 | HELPER=$1 | |
66 | ||
67 | test_expect_success "helper ($HELPER) has no existing data" ' | |
68 | check fill $HELPER <<-\EOF | |
69 | protocol=https | |
70 | host=example.com | |
71 | -- | |
2d6dc182 MM |
72 | protocol=https |
73 | host=example.com | |
e2770979 JK |
74 | username=askpass-username |
75 | password=askpass-password | |
76 | -- | |
77 | askpass: Username for '\''https://example.com'\'': | |
78 | askpass: Password for '\''https://askpass-username@example.com'\'': | |
79 | EOF | |
80 | ' | |
81 | ||
82 | test_expect_success "helper ($HELPER) stores password" ' | |
83 | check approve $HELPER <<-\EOF | |
84 | protocol=https | |
85 | host=example.com | |
86 | username=store-user | |
87 | password=store-pass | |
88 | EOF | |
89 | ' | |
90 | ||
91 | test_expect_success "helper ($HELPER) can retrieve password" ' | |
92 | check fill $HELPER <<-\EOF | |
93 | protocol=https | |
94 | host=example.com | |
95 | -- | |
2d6dc182 MM |
96 | protocol=https |
97 | host=example.com | |
e2770979 JK |
98 | username=store-user |
99 | password=store-pass | |
100 | -- | |
101 | EOF | |
102 | ' | |
103 | ||
104 | test_expect_success "helper ($HELPER) requires matching protocol" ' | |
105 | check fill $HELPER <<-\EOF | |
106 | protocol=http | |
107 | host=example.com | |
108 | -- | |
2d6dc182 MM |
109 | protocol=http |
110 | host=example.com | |
e2770979 JK |
111 | username=askpass-username |
112 | password=askpass-password | |
113 | -- | |
114 | askpass: Username for '\''http://example.com'\'': | |
115 | askpass: Password for '\''http://askpass-username@example.com'\'': | |
116 | EOF | |
117 | ' | |
118 | ||
119 | test_expect_success "helper ($HELPER) requires matching host" ' | |
120 | check fill $HELPER <<-\EOF | |
121 | protocol=https | |
122 | host=other.tld | |
123 | -- | |
2d6dc182 MM |
124 | protocol=https |
125 | host=other.tld | |
e2770979 JK |
126 | username=askpass-username |
127 | password=askpass-password | |
128 | -- | |
129 | askpass: Username for '\''https://other.tld'\'': | |
130 | askpass: Password for '\''https://askpass-username@other.tld'\'': | |
131 | EOF | |
132 | ' | |
133 | ||
134 | test_expect_success "helper ($HELPER) requires matching username" ' | |
135 | check fill $HELPER <<-\EOF | |
136 | protocol=https | |
137 | host=example.com | |
138 | username=other | |
139 | -- | |
2d6dc182 MM |
140 | protocol=https |
141 | host=example.com | |
e2770979 JK |
142 | username=other |
143 | password=askpass-password | |
144 | -- | |
145 | askpass: Password for '\''https://other@example.com'\'': | |
146 | EOF | |
147 | ' | |
148 | ||
149 | test_expect_success "helper ($HELPER) requires matching path" ' | |
150 | test_config credential.usehttppath true && | |
151 | check approve $HELPER <<-\EOF && | |
152 | protocol=http | |
153 | host=path.tld | |
154 | path=foo.git | |
155 | username=user | |
156 | password=pass | |
157 | EOF | |
158 | check fill $HELPER <<-\EOF | |
159 | protocol=http | |
160 | host=path.tld | |
161 | path=bar.git | |
162 | -- | |
2d6dc182 MM |
163 | protocol=http |
164 | host=path.tld | |
165 | path=bar.git | |
e2770979 JK |
166 | username=askpass-username |
167 | password=askpass-password | |
168 | -- | |
169 | askpass: Username for '\''http://path.tld/bar.git'\'': | |
170 | askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'': | |
171 | EOF | |
172 | ' | |
173 | ||
aeb21ce2 H |
174 | test_expect_success "helper ($HELPER) overwrites on store" ' |
175 | check approve $HELPER <<-\EOF && | |
176 | protocol=https | |
177 | host=example.com | |
178 | username=user-overwrite | |
179 | password=pass1 | |
180 | EOF | |
181 | check approve $HELPER <<-\EOF && | |
182 | protocol=https | |
183 | host=example.com | |
184 | username=user-overwrite | |
185 | password=pass2 | |
186 | EOF | |
187 | check fill $HELPER <<-\EOF && | |
188 | protocol=https | |
189 | host=example.com | |
190 | username=user-overwrite | |
191 | -- | |
192 | protocol=https | |
193 | host=example.com | |
194 | username=user-overwrite | |
195 | password=pass2 | |
196 | EOF | |
197 | check reject $HELPER <<-\EOF && | |
198 | protocol=https | |
199 | host=example.com | |
200 | username=user-overwrite | |
201 | password=pass2 | |
202 | EOF | |
203 | check fill $HELPER <<-\EOF | |
204 | protocol=https | |
205 | host=example.com | |
206 | username=user-overwrite | |
207 | -- | |
208 | protocol=https | |
209 | host=example.com | |
210 | username=user-overwrite | |
211 | password=askpass-password | |
212 | -- | |
213 | askpass: Password for '\''https://user-overwrite@example.com'\'': | |
214 | EOF | |
215 | ' | |
216 | ||
e2770979 JK |
217 | test_expect_success "helper ($HELPER) can forget host" ' |
218 | check reject $HELPER <<-\EOF && | |
219 | protocol=https | |
220 | host=example.com | |
221 | EOF | |
222 | check fill $HELPER <<-\EOF | |
223 | protocol=https | |
224 | host=example.com | |
225 | -- | |
2d6dc182 MM |
226 | protocol=https |
227 | host=example.com | |
e2770979 JK |
228 | username=askpass-username |
229 | password=askpass-password | |
230 | -- | |
231 | askpass: Username for '\''https://example.com'\'': | |
232 | askpass: Password for '\''https://askpass-username@example.com'\'': | |
233 | EOF | |
234 | ' | |
235 | ||
236 | test_expect_success "helper ($HELPER) can store multiple users" ' | |
237 | check approve $HELPER <<-\EOF && | |
238 | protocol=https | |
239 | host=example.com | |
240 | username=user1 | |
241 | password=pass1 | |
242 | EOF | |
243 | check approve $HELPER <<-\EOF && | |
244 | protocol=https | |
245 | host=example.com | |
246 | username=user2 | |
247 | password=pass2 | |
248 | EOF | |
249 | check fill $HELPER <<-\EOF && | |
250 | protocol=https | |
251 | host=example.com | |
252 | username=user1 | |
253 | -- | |
2d6dc182 MM |
254 | protocol=https |
255 | host=example.com | |
e2770979 JK |
256 | username=user1 |
257 | password=pass1 | |
258 | EOF | |
259 | check fill $HELPER <<-\EOF | |
260 | protocol=https | |
261 | host=example.com | |
262 | username=user2 | |
263 | -- | |
2d6dc182 MM |
264 | protocol=https |
265 | host=example.com | |
e2770979 JK |
266 | username=user2 |
267 | password=pass2 | |
268 | EOF | |
269 | ' | |
270 | ||
aeb21ce2 H |
271 | test_expect_success "helper ($HELPER) does not erase a password distinct from input" ' |
272 | check approve $HELPER <<-\EOF && | |
273 | protocol=https | |
274 | host=example.com | |
275 | username=user-distinct-pass | |
276 | password=pass1 | |
277 | EOF | |
278 | check reject $HELPER <<-\EOF && | |
279 | protocol=https | |
280 | host=example.com | |
281 | username=user-distinct-pass | |
282 | password=pass2 | |
283 | EOF | |
284 | check fill $HELPER <<-\EOF | |
285 | protocol=https | |
286 | host=example.com | |
287 | username=user-distinct-pass | |
288 | -- | |
289 | protocol=https | |
290 | host=example.com | |
291 | username=user-distinct-pass | |
292 | password=pass1 | |
293 | EOF | |
294 | ' | |
295 | ||
e2770979 JK |
296 | test_expect_success "helper ($HELPER) can forget user" ' |
297 | check reject $HELPER <<-\EOF && | |
298 | protocol=https | |
299 | host=example.com | |
300 | username=user1 | |
301 | EOF | |
302 | check fill $HELPER <<-\EOF | |
303 | protocol=https | |
304 | host=example.com | |
305 | username=user1 | |
306 | -- | |
2d6dc182 MM |
307 | protocol=https |
308 | host=example.com | |
e2770979 JK |
309 | username=user1 |
310 | password=askpass-password | |
311 | -- | |
312 | askpass: Password for '\''https://user1@example.com'\'': | |
313 | EOF | |
314 | ' | |
315 | ||
316 | test_expect_success "helper ($HELPER) remembers other user" ' | |
317 | check fill $HELPER <<-\EOF | |
318 | protocol=https | |
319 | host=example.com | |
320 | username=user2 | |
321 | -- | |
2d6dc182 MM |
322 | protocol=https |
323 | host=example.com | |
e2770979 JK |
324 | username=user2 |
325 | password=pass2 | |
326 | EOF | |
327 | ' | |
3c90bda6 JB |
328 | |
329 | test_expect_success "helper ($HELPER) can store empty username" ' | |
330 | check approve $HELPER <<-\EOF && | |
331 | protocol=https | |
332 | host=sso.tld | |
333 | username= | |
334 | password= | |
335 | EOF | |
336 | check fill $HELPER <<-\EOF | |
337 | protocol=https | |
338 | host=sso.tld | |
339 | -- | |
340 | protocol=https | |
341 | host=sso.tld | |
342 | username= | |
343 | password= | |
344 | EOF | |
345 | ' | |
71201ab0 | 346 | |
6c26da84 H |
347 | test_expect_success "helper ($HELPER) erases all matching credentials" ' |
348 | check approve $HELPER <<-\EOF && | |
349 | protocol=https | |
350 | host=example.com | |
351 | username=user-erase1 | |
352 | password=pass1 | |
353 | EOF | |
354 | check approve $HELPER <<-\EOF && | |
355 | protocol=https | |
356 | host=example.com | |
357 | username=user-erase2 | |
358 | password=pass1 | |
359 | EOF | |
360 | check reject $HELPER <<-\EOF && | |
361 | protocol=https | |
362 | host=example.com | |
363 | EOF | |
364 | check fill $HELPER <<-\EOF | |
365 | protocol=https | |
366 | host=example.com | |
367 | -- | |
368 | protocol=https | |
369 | host=example.com | |
370 | username=askpass-username | |
371 | password=askpass-password | |
372 | -- | |
373 | askpass: Username for '\''https://example.com'\'': | |
374 | askpass: Password for '\''https://askpass-username@example.com'\'': | |
375 | EOF | |
376 | ' | |
377 | ||
71201ab0 TB |
378 | : ${GIT_TEST_LONG_CRED_BUFFER:=1024} |
379 | # 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL | |
380 | LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23)) | |
381 | LONG_VALUE=$(perl -e 'print "a" x shift' $LONG_VALUE_LEN) | |
382 | ||
383 | test_expect_success "helper ($HELPER) not confused by long header" ' | |
384 | check approve $HELPER <<-\EOF && | |
385 | protocol=https | |
386 | host=victim.example.com | |
387 | username=user | |
388 | password=to-be-stolen | |
389 | EOF | |
390 | ||
391 | check fill $HELPER <<-EOF | |
392 | protocol=https | |
393 | host=badguy.example.com | |
394 | wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com | |
395 | -- | |
396 | protocol=https | |
397 | host=badguy.example.com | |
398 | username=askpass-username | |
399 | password=askpass-password | |
400 | wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com | |
401 | -- | |
402 | askpass: Username for '\''https://badguy.example.com'\'': | |
403 | askpass: Password for '\''https://askpass-username@badguy.example.com'\'': | |
404 | EOF | |
405 | ' | |
e2770979 JK |
406 | } |
407 | ||
408 | helper_test_timeout() { | |
409 | HELPER="$*" | |
410 | ||
411 | test_expect_success "helper ($HELPER) times out" ' | |
412 | check approve "$HELPER" <<-\EOF && | |
413 | protocol=https | |
414 | host=timeout.tld | |
415 | username=user | |
416 | password=pass | |
417 | EOF | |
418 | sleep 2 && | |
419 | check fill "$HELPER" <<-\EOF | |
420 | protocol=https | |
421 | host=timeout.tld | |
422 | -- | |
2d6dc182 MM |
423 | protocol=https |
424 | host=timeout.tld | |
e2770979 JK |
425 | username=askpass-username |
426 | password=askpass-password | |
427 | -- | |
428 | askpass: Username for '\''https://timeout.tld'\'': | |
429 | askpass: Password for '\''https://askpass-username@timeout.tld'\'': | |
430 | EOF | |
431 | ' | |
432 | } | |
abca927d | 433 | |
a5c76569 H |
434 | helper_test_oauth_refresh_token() { |
435 | HELPER=$1 | |
436 | ||
437 | test_expect_success "helper ($HELPER) stores oauth_refresh_token" ' | |
438 | check approve $HELPER <<-\EOF | |
439 | protocol=https | |
440 | host=example.com | |
441 | username=user4 | |
442 | password=pass | |
443 | oauth_refresh_token=xyzzy | |
444 | EOF | |
445 | ' | |
446 | ||
447 | test_expect_success "helper ($HELPER) gets oauth_refresh_token" ' | |
448 | check fill $HELPER <<-\EOF | |
449 | protocol=https | |
450 | host=example.com | |
451 | username=user4 | |
452 | -- | |
453 | protocol=https | |
454 | host=example.com | |
455 | username=user4 | |
456 | password=pass | |
457 | oauth_refresh_token=xyzzy | |
458 | -- | |
459 | EOF | |
460 | ' | |
461 | } | |
462 | ||
c049216f | 463 | write_script askpass <<\EOF |
abca927d | 464 | echo >&2 askpass: $* |
5a435202 | 465 | what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z) |
abca927d JK |
466 | echo "askpass-$what" |
467 | EOF | |
abca927d JK |
468 | GIT_ASKPASS="$PWD/askpass" |
469 | export GIT_ASKPASS |