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