]>
Commit | Line | Data |
---|---|---|
abca927d JK |
1 | #!/bin/sh |
2 | ||
3 | test_description='basic credential helper tests' | |
4 | . ./test-lib.sh | |
5 | . "$TEST_DIRECTORY"/lib-credential.sh | |
6 | ||
7 | test_expect_success 'setup helper scripts' ' | |
8 | cat >dump <<-\EOF && | |
dd64267f | 9 | whoami=$(echo $0 | sed s/.*git-credential-//) |
abca927d | 10 | echo >&2 "$whoami: $*" |
78ed1d2d MG |
11 | OIFS=$IFS |
12 | IFS== | |
13 | while read key value; do | |
abca927d JK |
14 | echo >&2 "$whoami: $key=$value" |
15 | eval "$key=$value" | |
16 | done | |
78ed1d2d | 17 | IFS=$OIFS |
abca927d JK |
18 | EOF |
19 | ||
3d9f5b67 | 20 | write_script git-credential-useless <<-\EOF && |
abca927d JK |
21 | . ./dump |
22 | exit 0 | |
23 | EOF | |
abca927d | 24 | |
a88dbd2f JK |
25 | write_script git-credential-quit <<-\EOF && |
26 | . ./dump | |
27 | echo quit=1 | |
28 | EOF | |
29 | ||
3d9f5b67 | 30 | write_script git-credential-verbatim <<-\EOF && |
abca927d JK |
31 | user=$1; shift |
32 | pass=$1; shift | |
33 | . ./dump | |
34 | test -z "$user" || echo username=$user | |
35 | test -z "$pass" || echo password=$pass | |
36 | EOF | |
abca927d | 37 | |
d208bfdf H |
38 | write_script git-credential-verbatim-with-expiry <<-\EOF && |
39 | user=$1; shift | |
40 | pass=$1; shift | |
41 | pexpiry=$1; shift | |
42 | . ./dump | |
43 | test -z "$user" || echo username=$user | |
44 | test -z "$pass" || echo password=$pass | |
45 | test -z "$pexpiry" || echo password_expiry_utc=$pexpiry | |
46 | EOF | |
47 | ||
abca927d JK |
48 | PATH="$PWD:$PATH" |
49 | ' | |
50 | ||
51 | test_expect_success 'credential_fill invokes helper' ' | |
52 | check fill "verbatim foo bar" <<-\EOF | |
73aafe9b JK |
53 | protocol=http |
54 | host=example.com | |
abca927d | 55 | -- |
73aafe9b JK |
56 | protocol=http |
57 | host=example.com | |
abca927d JK |
58 | username=foo |
59 | password=bar | |
60 | -- | |
61 | verbatim: get | |
73aafe9b JK |
62 | verbatim: protocol=http |
63 | verbatim: host=example.com | |
abca927d JK |
64 | EOF |
65 | ' | |
66 | ||
67 | test_expect_success 'credential_fill invokes multiple helpers' ' | |
68 | check fill useless "verbatim foo bar" <<-\EOF | |
73aafe9b JK |
69 | protocol=http |
70 | host=example.com | |
abca927d | 71 | -- |
73aafe9b JK |
72 | protocol=http |
73 | host=example.com | |
abca927d JK |
74 | username=foo |
75 | password=bar | |
76 | -- | |
77 | useless: get | |
73aafe9b JK |
78 | useless: protocol=http |
79 | useless: host=example.com | |
abca927d | 80 | verbatim: get |
73aafe9b JK |
81 | verbatim: protocol=http |
82 | verbatim: host=example.com | |
abca927d JK |
83 | EOF |
84 | ' | |
85 | ||
86 | test_expect_success 'credential_fill stops when we get a full response' ' | |
87 | check fill "verbatim one two" "verbatim three four" <<-\EOF | |
73aafe9b JK |
88 | protocol=http |
89 | host=example.com | |
abca927d | 90 | -- |
73aafe9b JK |
91 | protocol=http |
92 | host=example.com | |
abca927d JK |
93 | username=one |
94 | password=two | |
95 | -- | |
96 | verbatim: get | |
73aafe9b JK |
97 | verbatim: protocol=http |
98 | verbatim: host=example.com | |
abca927d JK |
99 | EOF |
100 | ' | |
101 | ||
102 | test_expect_success 'credential_fill continues through partial response' ' | |
103 | check fill "verbatim one \"\"" "verbatim two three" <<-\EOF | |
73aafe9b JK |
104 | protocol=http |
105 | host=example.com | |
abca927d | 106 | -- |
73aafe9b JK |
107 | protocol=http |
108 | host=example.com | |
abca927d JK |
109 | username=two |
110 | password=three | |
111 | -- | |
112 | verbatim: get | |
73aafe9b JK |
113 | verbatim: protocol=http |
114 | verbatim: host=example.com | |
abca927d | 115 | verbatim: get |
73aafe9b JK |
116 | verbatim: protocol=http |
117 | verbatim: host=example.com | |
abca927d JK |
118 | verbatim: username=one |
119 | EOF | |
120 | ' | |
121 | ||
d208bfdf H |
122 | test_expect_success 'credential_fill populates password_expiry_utc' ' |
123 | check fill "verbatim-with-expiry one two 9999999999" <<-\EOF | |
124 | protocol=http | |
125 | host=example.com | |
126 | -- | |
127 | protocol=http | |
128 | host=example.com | |
129 | username=one | |
130 | password=two | |
131 | password_expiry_utc=9999999999 | |
132 | -- | |
133 | verbatim-with-expiry: get | |
134 | verbatim-with-expiry: protocol=http | |
135 | verbatim-with-expiry: host=example.com | |
136 | EOF | |
137 | ' | |
138 | ||
139 | test_expect_success 'credential_fill ignores expired password' ' | |
140 | check fill "verbatim-with-expiry one two 5" "verbatim three four" <<-\EOF | |
141 | protocol=http | |
142 | host=example.com | |
143 | -- | |
144 | protocol=http | |
145 | host=example.com | |
146 | username=three | |
147 | password=four | |
148 | -- | |
149 | verbatim-with-expiry: get | |
150 | verbatim-with-expiry: protocol=http | |
151 | verbatim-with-expiry: host=example.com | |
152 | verbatim: get | |
153 | verbatim: protocol=http | |
154 | verbatim: host=example.com | |
155 | verbatim: username=one | |
156 | EOF | |
157 | ' | |
158 | ||
abca927d JK |
159 | test_expect_success 'credential_fill passes along metadata' ' |
160 | check fill "verbatim one two" <<-\EOF | |
161 | protocol=ftp | |
162 | host=example.com | |
163 | path=foo.git | |
164 | -- | |
2d6dc182 MM |
165 | protocol=ftp |
166 | host=example.com | |
167 | path=foo.git | |
abca927d JK |
168 | username=one |
169 | password=two | |
170 | -- | |
171 | verbatim: get | |
172 | verbatim: protocol=ftp | |
173 | verbatim: host=example.com | |
174 | verbatim: path=foo.git | |
175 | EOF | |
176 | ' | |
177 | ||
178 | test_expect_success 'credential_approve calls all helpers' ' | |
179 | check approve useless "verbatim one two" <<-\EOF | |
73aafe9b JK |
180 | protocol=http |
181 | host=example.com | |
abca927d JK |
182 | username=foo |
183 | password=bar | |
184 | -- | |
185 | -- | |
186 | useless: store | |
73aafe9b JK |
187 | useless: protocol=http |
188 | useless: host=example.com | |
abca927d JK |
189 | useless: username=foo |
190 | useless: password=bar | |
191 | verbatim: store | |
73aafe9b JK |
192 | verbatim: protocol=http |
193 | verbatim: host=example.com | |
abca927d JK |
194 | verbatim: username=foo |
195 | verbatim: password=bar | |
196 | EOF | |
197 | ' | |
198 | ||
d208bfdf H |
199 | test_expect_success 'credential_approve stores password expiry' ' |
200 | check approve useless <<-\EOF | |
201 | protocol=http | |
202 | host=example.com | |
203 | username=foo | |
204 | password=bar | |
205 | password_expiry_utc=9999999999 | |
206 | -- | |
207 | -- | |
208 | useless: store | |
209 | useless: protocol=http | |
210 | useless: host=example.com | |
211 | useless: username=foo | |
212 | useless: password=bar | |
213 | useless: password_expiry_utc=9999999999 | |
214 | EOF | |
215 | ' | |
216 | ||
abca927d JK |
217 | test_expect_success 'do not bother storing password-less credential' ' |
218 | check approve useless <<-\EOF | |
73aafe9b JK |
219 | protocol=http |
220 | host=example.com | |
abca927d JK |
221 | username=foo |
222 | -- | |
223 | -- | |
224 | EOF | |
225 | ' | |
226 | ||
d208bfdf H |
227 | test_expect_success 'credential_approve does not store expired password' ' |
228 | check approve useless <<-\EOF | |
229 | protocol=http | |
230 | host=example.com | |
231 | username=foo | |
232 | password=bar | |
233 | password_expiry_utc=5 | |
234 | -- | |
235 | -- | |
236 | EOF | |
237 | ' | |
abca927d JK |
238 | |
239 | test_expect_success 'credential_reject calls all helpers' ' | |
240 | check reject useless "verbatim one two" <<-\EOF | |
73aafe9b JK |
241 | protocol=http |
242 | host=example.com | |
abca927d JK |
243 | username=foo |
244 | password=bar | |
245 | -- | |
246 | -- | |
247 | useless: erase | |
73aafe9b JK |
248 | useless: protocol=http |
249 | useless: host=example.com | |
abca927d JK |
250 | useless: username=foo |
251 | useless: password=bar | |
252 | verbatim: erase | |
73aafe9b JK |
253 | verbatim: protocol=http |
254 | verbatim: host=example.com | |
abca927d JK |
255 | verbatim: username=foo |
256 | verbatim: password=bar | |
257 | EOF | |
258 | ' | |
259 | ||
d208bfdf H |
260 | test_expect_success 'credential_reject erases credential regardless of expiry' ' |
261 | check reject useless <<-\EOF | |
262 | protocol=http | |
263 | host=example.com | |
264 | username=foo | |
265 | password=bar | |
266 | password_expiry_utc=5 | |
267 | -- | |
268 | -- | |
269 | useless: erase | |
270 | useless: protocol=http | |
271 | useless: host=example.com | |
272 | useless: username=foo | |
273 | useless: password=bar | |
274 | useless: password_expiry_utc=5 | |
275 | EOF | |
276 | ' | |
277 | ||
abca927d JK |
278 | test_expect_success 'usernames can be preserved' ' |
279 | check fill "verbatim \"\" three" <<-\EOF | |
73aafe9b JK |
280 | protocol=http |
281 | host=example.com | |
abca927d JK |
282 | username=one |
283 | -- | |
73aafe9b JK |
284 | protocol=http |
285 | host=example.com | |
abca927d JK |
286 | username=one |
287 | password=three | |
288 | -- | |
289 | verbatim: get | |
73aafe9b JK |
290 | verbatim: protocol=http |
291 | verbatim: host=example.com | |
abca927d JK |
292 | verbatim: username=one |
293 | EOF | |
294 | ' | |
295 | ||
296 | test_expect_success 'usernames can be overridden' ' | |
297 | check fill "verbatim two three" <<-\EOF | |
73aafe9b JK |
298 | protocol=http |
299 | host=example.com | |
abca927d JK |
300 | username=one |
301 | -- | |
73aafe9b JK |
302 | protocol=http |
303 | host=example.com | |
abca927d JK |
304 | username=two |
305 | password=three | |
306 | -- | |
307 | verbatim: get | |
73aafe9b JK |
308 | verbatim: protocol=http |
309 | verbatim: host=example.com | |
abca927d JK |
310 | verbatim: username=one |
311 | EOF | |
312 | ' | |
313 | ||
314 | test_expect_success 'do not bother completing already-full credential' ' | |
315 | check fill "verbatim three four" <<-\EOF | |
73aafe9b JK |
316 | protocol=http |
317 | host=example.com | |
abca927d JK |
318 | username=one |
319 | password=two | |
320 | -- | |
73aafe9b JK |
321 | protocol=http |
322 | host=example.com | |
abca927d JK |
323 | username=one |
324 | password=two | |
325 | -- | |
326 | EOF | |
327 | ' | |
328 | ||
329 | # We can't test the basic terminal password prompt here because | |
330 | # getpass() tries too hard to find the real terminal. But if our | |
331 | # askpass helper is run, we know the internal getpass is working. | |
332 | test_expect_success 'empty helper list falls back to internal getpass' ' | |
333 | check fill <<-\EOF | |
73aafe9b JK |
334 | protocol=http |
335 | host=example.com | |
abca927d | 336 | -- |
73aafe9b JK |
337 | protocol=http |
338 | host=example.com | |
abca927d JK |
339 | username=askpass-username |
340 | password=askpass-password | |
341 | -- | |
73aafe9b JK |
342 | askpass: Username for '\''http://example.com'\'': |
343 | askpass: Password for '\''http://askpass-username@example.com'\'': | |
abca927d JK |
344 | EOF |
345 | ' | |
346 | ||
347 | test_expect_success 'internal getpass does not ask for known username' ' | |
348 | check fill <<-\EOF | |
73aafe9b JK |
349 | protocol=http |
350 | host=example.com | |
abca927d JK |
351 | username=foo |
352 | -- | |
73aafe9b JK |
353 | protocol=http |
354 | host=example.com | |
abca927d JK |
355 | username=foo |
356 | password=askpass-password | |
357 | -- | |
73aafe9b | 358 | askpass: Password for '\''http://foo@example.com'\'': |
abca927d JK |
359 | EOF |
360 | ' | |
361 | ||
567ad2c0 TK |
362 | test_expect_success 'git-credential respects core.askPass' ' |
363 | write_script alternate-askpass <<-\EOF && | |
364 | echo >&2 "alternate askpass invoked" | |
365 | echo alternate-value | |
366 | EOF | |
367 | test_config core.askpass "$PWD/alternate-askpass" && | |
368 | ( | |
369 | # unset GIT_ASKPASS set by lib-credential.sh which would | |
370 | # override our config, but do so in a subshell so that we do | |
371 | # not interfere with other tests | |
372 | sane_unset GIT_ASKPASS && | |
373 | check fill <<-\EOF | |
374 | protocol=http | |
375 | host=example.com | |
376 | -- | |
377 | protocol=http | |
378 | host=example.com | |
379 | username=alternate-value | |
380 | password=alternate-value | |
381 | -- | |
382 | alternate askpass invoked | |
383 | alternate askpass invoked | |
384 | EOF | |
385 | ) | |
386 | ' | |
387 | ||
11825072 JK |
388 | HELPER="!f() { |
389 | cat >/dev/null | |
390 | echo username=foo | |
391 | echo password=bar | |
392 | }; f" | |
393 | test_expect_success 'respect configured credentials' ' | |
394 | test_config credential.helper "$HELPER" && | |
395 | check fill <<-\EOF | |
73aafe9b JK |
396 | protocol=http |
397 | host=example.com | |
11825072 | 398 | -- |
73aafe9b JK |
399 | protocol=http |
400 | host=example.com | |
11825072 JK |
401 | username=foo |
402 | password=bar | |
403 | -- | |
404 | EOF | |
405 | ' | |
406 | ||
407 | test_expect_success 'match configured credential' ' | |
408 | test_config credential.https://example.com.helper "$HELPER" && | |
409 | check fill <<-\EOF | |
410 | protocol=https | |
411 | host=example.com | |
412 | path=repo.git | |
413 | -- | |
2d6dc182 MM |
414 | protocol=https |
415 | host=example.com | |
11825072 JK |
416 | username=foo |
417 | password=bar | |
418 | -- | |
419 | EOF | |
420 | ' | |
421 | ||
422 | test_expect_success 'do not match configured credential' ' | |
423 | test_config credential.https://foo.helper "$HELPER" && | |
424 | check fill <<-\EOF | |
425 | protocol=https | |
426 | host=bar | |
427 | -- | |
2d6dc182 MM |
428 | protocol=https |
429 | host=bar | |
11825072 JK |
430 | username=askpass-username |
431 | password=askpass-password | |
432 | -- | |
433 | askpass: Username for '\''https://bar'\'': | |
434 | askpass: Password for '\''https://askpass-username@bar'\'': | |
435 | EOF | |
436 | ' | |
437 | ||
588c70e1 | 438 | test_expect_success 'match multiple configured helpers' ' |
439 | test_config credential.helper "verbatim \"\" \"\"" && | |
440 | test_config credential.https://example.com.helper "$HELPER" && | |
441 | check fill <<-\EOF | |
442 | protocol=https | |
443 | host=example.com | |
444 | path=repo.git | |
445 | -- | |
446 | protocol=https | |
447 | host=example.com | |
448 | username=foo | |
449 | password=bar | |
450 | -- | |
451 | verbatim: get | |
452 | verbatim: protocol=https | |
453 | verbatim: host=example.com | |
454 | EOF | |
455 | ' | |
456 | ||
457 | test_expect_success 'match multiple configured helpers with URLs' ' | |
458 | test_config credential.https://example.com/repo.git.helper "verbatim \"\" \"\"" && | |
459 | test_config credential.https://example.com.helper "$HELPER" && | |
460 | check fill <<-\EOF | |
461 | protocol=https | |
462 | host=example.com | |
463 | path=repo.git | |
464 | -- | |
465 | protocol=https | |
466 | host=example.com | |
467 | username=foo | |
468 | password=bar | |
469 | -- | |
470 | verbatim: get | |
471 | verbatim: protocol=https | |
472 | verbatim: host=example.com | |
473 | EOF | |
474 | ' | |
475 | ||
476 | test_expect_success 'match percent-encoded values' ' | |
477 | test_config credential.https://example.com/%2566.git.helper "$HELPER" && | |
478 | check fill <<-\EOF | |
479 | url=https://example.com/%2566.git | |
480 | -- | |
481 | protocol=https | |
482 | host=example.com | |
483 | username=foo | |
484 | password=bar | |
485 | -- | |
486 | EOF | |
487 | ' | |
488 | ||
b44d0118 | 489 | test_expect_success 'match percent-encoded UTF-8 values in path' ' |
490 | test_config credential.https://example.com.useHttpPath true && | |
491 | test_config credential.https://example.com/perú.git.helper "$HELPER" && | |
492 | check fill <<-\EOF | |
493 | url=https://example.com/per%C3%BA.git | |
494 | -- | |
495 | protocol=https | |
496 | host=example.com | |
497 | path=perú.git | |
498 | username=foo | |
499 | password=bar | |
500 | -- | |
501 | EOF | |
502 | ' | |
503 | ||
504 | test_expect_success 'match percent-encoded values in username' ' | |
505 | test_config credential.https://user%2fname@example.com/foo/bar.git.helper "$HELPER" && | |
506 | check fill <<-\EOF | |
507 | url=https://user%2fname@example.com/foo/bar.git | |
508 | -- | |
509 | protocol=https | |
510 | host=example.com | |
511 | username=foo | |
512 | password=bar | |
513 | -- | |
514 | EOF | |
515 | ' | |
516 | ||
517 | test_expect_success 'fetch with multiple path components' ' | |
518 | test_unconfig credential.helper && | |
519 | test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" && | |
520 | check fill <<-\EOF | |
521 | url=https://example.com/foo/repo.git | |
522 | -- | |
523 | protocol=https | |
524 | host=example.com | |
525 | username=foo | |
526 | password=bar | |
527 | -- | |
528 | verbatim: get | |
529 | verbatim: protocol=https | |
530 | verbatim: host=example.com | |
531 | EOF | |
532 | ' | |
533 | ||
d5742425 JK |
534 | test_expect_success 'pull username from config' ' |
535 | test_config credential.https://example.com.username foo && | |
536 | check fill <<-\EOF | |
537 | protocol=https | |
538 | host=example.com | |
539 | -- | |
2d6dc182 MM |
540 | protocol=https |
541 | host=example.com | |
d5742425 JK |
542 | username=foo |
543 | password=askpass-password | |
544 | -- | |
545 | askpass: Password for '\''https://foo@example.com'\'': | |
546 | EOF | |
547 | ' | |
548 | ||
588c70e1 | 549 | test_expect_success 'honors username from URL over helper (URL)' ' |
550 | test_config credential.https://example.com.username bob && | |
551 | test_config credential.https://example.com.helper "verbatim \"\" bar" && | |
552 | check fill <<-\EOF | |
553 | url=https://alice@example.com | |
554 | -- | |
555 | protocol=https | |
556 | host=example.com | |
557 | username=alice | |
558 | password=bar | |
559 | -- | |
560 | verbatim: get | |
561 | verbatim: protocol=https | |
562 | verbatim: host=example.com | |
563 | verbatim: username=alice | |
564 | EOF | |
565 | ' | |
566 | ||
567 | test_expect_success 'honors username from URL over helper (components)' ' | |
568 | test_config credential.https://example.com.username bob && | |
569 | test_config credential.https://example.com.helper "verbatim \"\" bar" && | |
570 | check fill <<-\EOF | |
571 | protocol=https | |
572 | host=example.com | |
573 | username=alice | |
574 | -- | |
575 | protocol=https | |
576 | host=example.com | |
577 | username=alice | |
578 | password=bar | |
579 | -- | |
580 | verbatim: get | |
581 | verbatim: protocol=https | |
582 | verbatim: host=example.com | |
583 | verbatim: username=alice | |
584 | EOF | |
585 | ' | |
586 | ||
82eb2498 | 587 | test_expect_success 'last matching username wins' ' |
588c70e1 | 588 | test_config credential.https://example.com/path.git.username bob && |
589 | test_config credential.https://example.com.username alice && | |
590 | test_config credential.https://example.com.helper "verbatim \"\" bar" && | |
591 | check fill <<-\EOF | |
592 | url=https://example.com/path.git | |
593 | -- | |
594 | protocol=https | |
595 | host=example.com | |
596 | username=alice | |
597 | password=bar | |
598 | -- | |
599 | verbatim: get | |
600 | verbatim: protocol=https | |
601 | verbatim: host=example.com | |
602 | verbatim: username=alice | |
603 | EOF | |
604 | ' | |
605 | ||
a78fbb4f JK |
606 | test_expect_success 'http paths can be part of context' ' |
607 | check fill "verbatim foo bar" <<-\EOF && | |
608 | protocol=https | |
609 | host=example.com | |
610 | path=foo.git | |
611 | -- | |
2d6dc182 MM |
612 | protocol=https |
613 | host=example.com | |
a78fbb4f JK |
614 | username=foo |
615 | password=bar | |
616 | -- | |
617 | verbatim: get | |
618 | verbatim: protocol=https | |
619 | verbatim: host=example.com | |
620 | EOF | |
621 | test_config credential.https://example.com.useHttpPath true && | |
622 | check fill "verbatim foo bar" <<-\EOF | |
623 | protocol=https | |
624 | host=example.com | |
625 | path=foo.git | |
626 | -- | |
2d6dc182 MM |
627 | protocol=https |
628 | host=example.com | |
629 | path=foo.git | |
a78fbb4f JK |
630 | username=foo |
631 | password=bar | |
632 | -- | |
633 | verbatim: get | |
634 | verbatim: protocol=https | |
635 | verbatim: host=example.com | |
636 | verbatim: path=foo.git | |
637 | EOF | |
638 | ' | |
639 | ||
46fd7b39 | 640 | test_expect_success 'context uses urlmatch' ' |
641 | test_config "credential.https://*.org.useHttpPath" true && | |
642 | check fill "verbatim foo bar" <<-\EOF | |
643 | protocol=https | |
644 | host=example.org | |
645 | path=foo.git | |
646 | -- | |
647 | protocol=https | |
648 | host=example.org | |
649 | path=foo.git | |
650 | username=foo | |
651 | password=bar | |
652 | -- | |
653 | verbatim: get | |
654 | verbatim: protocol=https | |
655 | verbatim: host=example.org | |
656 | verbatim: path=foo.git | |
657 | EOF | |
658 | ' | |
659 | ||
59b38652 JK |
660 | test_expect_success 'helpers can abort the process' ' |
661 | test_must_fail git \ | |
a88dbd2f | 662 | -c credential.helper=quit \ |
59b38652 | 663 | -c credential.helper="verbatim foo bar" \ |
73aafe9b JK |
664 | credential fill >stdout 2>stderr <<-\EOF && |
665 | protocol=http | |
666 | host=example.com | |
667 | EOF | |
76b54ee9 | 668 | test_must_be_empty stdout && |
a88dbd2f JK |
669 | cat >expect <<-\EOF && |
670 | quit: get | |
73aafe9b JK |
671 | quit: protocol=http |
672 | quit: host=example.com | |
a88dbd2f JK |
673 | fatal: credential helper '\''quit'\'' told us to quit |
674 | EOF | |
1108cea7 | 675 | test_cmp expect stderr |
59b38652 JK |
676 | ' |
677 | ||
24321375 JK |
678 | test_expect_success 'empty helper spec resets helper list' ' |
679 | test_config credential.helper "verbatim file file" && | |
680 | check fill "" "verbatim cmdline cmdline" <<-\EOF | |
73aafe9b JK |
681 | protocol=http |
682 | host=example.com | |
24321375 | 683 | -- |
73aafe9b JK |
684 | protocol=http |
685 | host=example.com | |
24321375 JK |
686 | username=cmdline |
687 | password=cmdline | |
688 | -- | |
689 | verbatim: get | |
73aafe9b JK |
690 | verbatim: protocol=http |
691 | verbatim: host=example.com | |
24321375 JK |
692 | EOF |
693 | ' | |
694 | ||
8ba8ed56 JK |
695 | test_expect_success 'url parser rejects embedded newlines' ' |
696 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
9a6bbee8 | 697 | url=https://one.example.com?%0ahost=two.example.com/ |
8ba8ed56 JK |
698 | EOF |
699 | cat >expect <<-\EOF && | |
a397e9c2 | 700 | warning: url contains a newline in its path component: https://one.example.com?%0ahost=two.example.com/ |
fe29a9b7 | 701 | fatal: credential url cannot be parsed: https://one.example.com?%0ahost=two.example.com/ |
9a6bbee8 | 702 | EOF |
1108cea7 | 703 | test_cmp expect stderr |
9a6bbee8 JK |
704 | ' |
705 | ||
24036686 JK |
706 | test_expect_success 'host-less URLs are parsed as empty host' ' |
707 | check fill "verbatim foo bar" <<-\EOF | |
708 | url=cert:///path/to/cert.pem | |
c716fe4b | 709 | -- |
24036686 JK |
710 | protocol=cert |
711 | host= | |
712 | path=path/to/cert.pem | |
713 | username=foo | |
714 | password=bar | |
c716fe4b | 715 | -- |
24036686 JK |
716 | verbatim: get |
717 | verbatim: protocol=cert | |
718 | verbatim: host= | |
719 | verbatim: path=path/to/cert.pem | |
720 | EOF | |
721 | ' | |
722 | ||
8ba8ed56 JK |
723 | test_expect_success 'credential system refuses to work with missing host' ' |
724 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
725 | protocol=http | |
726 | EOF | |
727 | cat >expect <<-\EOF && | |
728 | fatal: refusing to work with credential missing host field | |
729 | EOF | |
1108cea7 | 730 | test_cmp expect stderr |
8ba8ed56 JK |
731 | ' |
732 | ||
733 | test_expect_success 'credential system refuses to work with missing protocol' ' | |
734 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
735 | host=example.com | |
736 | EOF | |
737 | cat >expect <<-\EOF && | |
738 | fatal: refusing to work with credential missing protocol field | |
9a6bbee8 | 739 | EOF |
1108cea7 | 740 | test_cmp expect stderr |
9a6bbee8 JK |
741 | ' |
742 | ||
4c5971e1 JK |
743 | # usage: check_host_and_path <url> <expected-host> <expected-path> |
744 | check_host_and_path () { | |
745 | # we always parse the path component, but we need this to make sure it | |
746 | # is passed to the helper | |
747 | test_config credential.useHTTPPath true && | |
748 | check fill "verbatim user pass" <<-EOF | |
749 | url=$1 | |
750 | -- | |
751 | protocol=https | |
752 | host=$2 | |
753 | path=$3 | |
754 | username=user | |
755 | password=pass | |
756 | -- | |
757 | verbatim: get | |
758 | verbatim: protocol=https | |
759 | verbatim: host=$2 | |
760 | verbatim: path=$3 | |
761 | EOF | |
762 | } | |
763 | ||
764 | test_expect_success 'url parser handles bare query marker' ' | |
765 | check_host_and_path https://example.com?foo.git example.com ?foo.git | |
766 | ' | |
767 | ||
768 | test_expect_success 'url parser handles bare fragment marker' ' | |
769 | check_host_and_path https://example.com#foo.git example.com "#foo.git" | |
770 | ' | |
771 | ||
772 | test_expect_success 'url parser not confused by encoded markers' ' | |
773 | check_host_and_path https://example.com%23%3f%2f/foo.git \ | |
774 | "example.com#?/" foo.git | |
775 | ' | |
776 | ||
9a121b0d JS |
777 | test_expect_success 'credential config with partial URLs' ' |
778 | echo "echo password=yep" | write_script git-credential-yep && | |
779 | test_write_lines url=https://user@example.com/repo.git >stdin && | |
780 | for partial in \ | |
781 | example.com \ | |
782 | user@example.com \ | |
783 | https:// \ | |
784 | https://example.com \ | |
785 | https://example.com/ \ | |
786 | https://user@example.com \ | |
787 | https://user@example.com/ \ | |
788 | https://example.com/repo.git \ | |
789 | https://user@example.com/repo.git \ | |
790 | /repo.git | |
791 | do | |
792 | git -c credential.$partial.helper=yep \ | |
793 | credential fill <stdin >stdout && | |
794 | grep yep stdout || | |
795 | return 1 | |
796 | done && | |
797 | ||
798 | for partial in \ | |
799 | dont.use.this \ | |
800 | http:// \ | |
801 | /repo | |
802 | do | |
803 | git -c credential.$partial.helper=yep \ | |
804 | credential fill <stdin >stdout && | |
805 | ! grep yep stdout || | |
806 | return 1 | |
807 | done && | |
808 | ||
809 | git -c credential.$partial.helper=yep \ | |
810 | -c credential.with%0anewline.username=uh-oh \ | |
811 | credential fill <stdin >stdout 2>stderr && | |
812 | test_i18ngrep "skipping credential lookup for key" stderr | |
813 | ' | |
814 | ||
abca927d | 815 | test_done |