Merge branch 'rt/format-zero-length-fix'
[git] / t / t0300-credentials.sh
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 &&
9         whoami=$(echo $0 | sed s/.*git-credential-//)
10         echo >&2 "$whoami: $*"
11         OIFS=$IFS
12         IFS==
13         while read key value; do
14                 echo >&2 "$whoami: $key=$value"
15                 eval "$key=$value"
16         done
17         IFS=$OIFS
18         EOF
19
20         write_script git-credential-useless <<-\EOF &&
21         . ./dump
22         exit 0
23         EOF
24
25         write_script git-credential-verbatim <<-\EOF &&
26         user=$1; shift
27         pass=$1; shift
28         . ./dump
29         test -z "$user" || echo username=$user
30         test -z "$pass" || echo password=$pass
31         EOF
32
33         PATH="$PWD:$PATH"
34 '
35
36 test_expect_success 'credential_fill invokes helper' '
37         check fill "verbatim foo bar" <<-\EOF
38         --
39         username=foo
40         password=bar
41         --
42         verbatim: get
43         EOF
44 '
45
46 test_expect_success 'credential_fill invokes multiple helpers' '
47         check fill useless "verbatim foo bar" <<-\EOF
48         --
49         username=foo
50         password=bar
51         --
52         useless: get
53         verbatim: get
54         EOF
55 '
56
57 test_expect_success 'credential_fill stops when we get a full response' '
58         check fill "verbatim one two" "verbatim three four" <<-\EOF
59         --
60         username=one
61         password=two
62         --
63         verbatim: get
64         EOF
65 '
66
67 test_expect_success 'credential_fill continues through partial response' '
68         check fill "verbatim one \"\"" "verbatim two three" <<-\EOF
69         --
70         username=two
71         password=three
72         --
73         verbatim: get
74         verbatim: get
75         verbatim: username=one
76         EOF
77 '
78
79 test_expect_success 'credential_fill passes along metadata' '
80         check fill "verbatim one two" <<-\EOF
81         protocol=ftp
82         host=example.com
83         path=foo.git
84         --
85         protocol=ftp
86         host=example.com
87         path=foo.git
88         username=one
89         password=two
90         --
91         verbatim: get
92         verbatim: protocol=ftp
93         verbatim: host=example.com
94         verbatim: path=foo.git
95         EOF
96 '
97
98 test_expect_success 'credential_approve calls all helpers' '
99         check approve useless "verbatim one two" <<-\EOF
100         username=foo
101         password=bar
102         --
103         --
104         useless: store
105         useless: username=foo
106         useless: password=bar
107         verbatim: store
108         verbatim: username=foo
109         verbatim: password=bar
110         EOF
111 '
112
113 test_expect_success 'do not bother storing password-less credential' '
114         check approve useless <<-\EOF
115         username=foo
116         --
117         --
118         EOF
119 '
120
121
122 test_expect_success 'credential_reject calls all helpers' '
123         check reject useless "verbatim one two" <<-\EOF
124         username=foo
125         password=bar
126         --
127         --
128         useless: erase
129         useless: username=foo
130         useless: password=bar
131         verbatim: erase
132         verbatim: username=foo
133         verbatim: password=bar
134         EOF
135 '
136
137 test_expect_success 'usernames can be preserved' '
138         check fill "verbatim \"\" three" <<-\EOF
139         username=one
140         --
141         username=one
142         password=three
143         --
144         verbatim: get
145         verbatim: username=one
146         EOF
147 '
148
149 test_expect_success 'usernames can be overridden' '
150         check fill "verbatim two three" <<-\EOF
151         username=one
152         --
153         username=two
154         password=three
155         --
156         verbatim: get
157         verbatim: username=one
158         EOF
159 '
160
161 test_expect_success 'do not bother completing already-full credential' '
162         check fill "verbatim three four" <<-\EOF
163         username=one
164         password=two
165         --
166         username=one
167         password=two
168         --
169         EOF
170 '
171
172 # We can't test the basic terminal password prompt here because
173 # getpass() tries too hard to find the real terminal. But if our
174 # askpass helper is run, we know the internal getpass is working.
175 test_expect_success 'empty helper list falls back to internal getpass' '
176         check fill <<-\EOF
177         --
178         username=askpass-username
179         password=askpass-password
180         --
181         askpass: Username:
182         askpass: Password:
183         EOF
184 '
185
186 test_expect_success 'internal getpass does not ask for known username' '
187         check fill <<-\EOF
188         username=foo
189         --
190         username=foo
191         password=askpass-password
192         --
193         askpass: Password:
194         EOF
195 '
196
197 HELPER="!f() {
198                 cat >/dev/null
199                 echo username=foo
200                 echo password=bar
201         }; f"
202 test_expect_success 'respect configured credentials' '
203         test_config credential.helper "$HELPER" &&
204         check fill <<-\EOF
205         --
206         username=foo
207         password=bar
208         --
209         EOF
210 '
211
212 test_expect_success 'match configured credential' '
213         test_config credential.https://example.com.helper "$HELPER" &&
214         check fill <<-\EOF
215         protocol=https
216         host=example.com
217         path=repo.git
218         --
219         protocol=https
220         host=example.com
221         username=foo
222         password=bar
223         --
224         EOF
225 '
226
227 test_expect_success 'do not match configured credential' '
228         test_config credential.https://foo.helper "$HELPER" &&
229         check fill <<-\EOF
230         protocol=https
231         host=bar
232         --
233         protocol=https
234         host=bar
235         username=askpass-username
236         password=askpass-password
237         --
238         askpass: Username for '\''https://bar'\'':
239         askpass: Password for '\''https://askpass-username@bar'\'':
240         EOF
241 '
242
243 test_expect_success 'match multiple configured helpers' '
244         test_config credential.helper "verbatim \"\" \"\"" &&
245         test_config credential.https://example.com.helper "$HELPER" &&
246         check fill <<-\EOF
247         protocol=https
248         host=example.com
249         path=repo.git
250         --
251         protocol=https
252         host=example.com
253         username=foo
254         password=bar
255         --
256         verbatim: get
257         verbatim: protocol=https
258         verbatim: host=example.com
259         EOF
260 '
261
262 test_expect_success 'match multiple configured helpers with URLs' '
263         test_config credential.https://example.com/repo.git.helper "verbatim \"\" \"\"" &&
264         test_config credential.https://example.com.helper "$HELPER" &&
265         check fill <<-\EOF
266         protocol=https
267         host=example.com
268         path=repo.git
269         --
270         protocol=https
271         host=example.com
272         username=foo
273         password=bar
274         --
275         verbatim: get
276         verbatim: protocol=https
277         verbatim: host=example.com
278         EOF
279 '
280
281 test_expect_success 'match percent-encoded values' '
282         test_config credential.https://example.com/%2566.git.helper "$HELPER" &&
283         check fill <<-\EOF
284         url=https://example.com/%2566.git
285         --
286         protocol=https
287         host=example.com
288         username=foo
289         password=bar
290         --
291         EOF
292 '
293
294 test_expect_success 'pull username from config' '
295         test_config credential.https://example.com.username foo &&
296         check fill <<-\EOF
297         protocol=https
298         host=example.com
299         --
300         protocol=https
301         host=example.com
302         username=foo
303         password=askpass-password
304         --
305         askpass: Password for '\''https://foo@example.com'\'':
306         EOF
307 '
308
309 test_expect_success 'honors username from URL over helper (URL)' '
310         test_config credential.https://example.com.username bob &&
311         test_config credential.https://example.com.helper "verbatim \"\" bar" &&
312         check fill <<-\EOF
313         url=https://alice@example.com
314         --
315         protocol=https
316         host=example.com
317         username=alice
318         password=bar
319         --
320         verbatim: get
321         verbatim: protocol=https
322         verbatim: host=example.com
323         verbatim: username=alice
324         EOF
325 '
326
327 test_expect_success 'honors username from URL over helper (components)' '
328         test_config credential.https://example.com.username bob &&
329         test_config credential.https://example.com.helper "verbatim \"\" bar" &&
330         check fill <<-\EOF
331         protocol=https
332         host=example.com
333         username=alice
334         --
335         protocol=https
336         host=example.com
337         username=alice
338         password=bar
339         --
340         verbatim: get
341         verbatim: protocol=https
342         verbatim: host=example.com
343         verbatim: username=alice
344         EOF
345 '
346
347 test_expect_success 'last matching username wins' '
348         test_config credential.https://example.com/path.git.username bob &&
349         test_config credential.https://example.com.username alice &&
350         test_config credential.https://example.com.helper "verbatim \"\" bar" &&
351         check fill <<-\EOF
352         url=https://example.com/path.git
353         --
354         protocol=https
355         host=example.com
356         username=alice
357         password=bar
358         --
359         verbatim: get
360         verbatim: protocol=https
361         verbatim: host=example.com
362         verbatim: username=alice
363         EOF
364 '
365
366 test_expect_success 'http paths can be part of context' '
367         check fill "verbatim foo bar" <<-\EOF &&
368         protocol=https
369         host=example.com
370         path=foo.git
371         --
372         protocol=https
373         host=example.com
374         username=foo
375         password=bar
376         --
377         verbatim: get
378         verbatim: protocol=https
379         verbatim: host=example.com
380         EOF
381         test_config credential.https://example.com.useHttpPath true &&
382         check fill "verbatim foo bar" <<-\EOF
383         protocol=https
384         host=example.com
385         path=foo.git
386         --
387         protocol=https
388         host=example.com
389         path=foo.git
390         username=foo
391         password=bar
392         --
393         verbatim: get
394         verbatim: protocol=https
395         verbatim: host=example.com
396         verbatim: path=foo.git
397         EOF
398 '
399
400 test_expect_success 'context uses urlmatch' '
401         test_config "credential.https://*.org.useHttpPath" true &&
402         check fill "verbatim foo bar" <<-\EOF
403         protocol=https
404         host=example.org
405         path=foo.git
406         --
407         protocol=https
408         host=example.org
409         path=foo.git
410         username=foo
411         password=bar
412         --
413         verbatim: get
414         verbatim: protocol=https
415         verbatim: host=example.org
416         verbatim: path=foo.git
417         EOF
418 '
419
420 test_expect_success 'helpers can abort the process' '
421         test_must_fail git \
422                 -c credential.helper="!f() { echo quit=1; }; f" \
423                 -c credential.helper="verbatim foo bar" \
424                 credential fill >stdout &&
425         test_must_be_empty stdout
426 '
427
428 test_expect_success 'empty helper spec resets helper list' '
429         test_config credential.helper "verbatim file file" &&
430         check fill "" "verbatim cmdline cmdline" <<-\EOF
431         --
432         username=cmdline
433         password=cmdline
434         --
435         verbatim: get
436         EOF
437 '
438
439 test_done