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