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