]>
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 JK |
37 | |
38 | PATH="$PWD:$PATH" | |
39 | ' | |
40 | ||
41 | test_expect_success 'credential_fill invokes helper' ' | |
42 | check fill "verbatim foo bar" <<-\EOF | |
73aafe9b JK |
43 | protocol=http |
44 | host=example.com | |
abca927d | 45 | -- |
73aafe9b JK |
46 | protocol=http |
47 | host=example.com | |
abca927d JK |
48 | username=foo |
49 | password=bar | |
50 | -- | |
51 | verbatim: get | |
73aafe9b JK |
52 | verbatim: protocol=http |
53 | verbatim: host=example.com | |
abca927d JK |
54 | EOF |
55 | ' | |
56 | ||
57 | test_expect_success 'credential_fill invokes multiple helpers' ' | |
58 | check fill useless "verbatim foo bar" <<-\EOF | |
73aafe9b JK |
59 | protocol=http |
60 | host=example.com | |
abca927d | 61 | -- |
73aafe9b JK |
62 | protocol=http |
63 | host=example.com | |
abca927d JK |
64 | username=foo |
65 | password=bar | |
66 | -- | |
67 | useless: get | |
73aafe9b JK |
68 | useless: protocol=http |
69 | useless: host=example.com | |
abca927d | 70 | verbatim: get |
73aafe9b JK |
71 | verbatim: protocol=http |
72 | verbatim: host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
78 | protocol=http |
79 | host=example.com | |
abca927d | 80 | -- |
73aafe9b JK |
81 | protocol=http |
82 | host=example.com | |
abca927d JK |
83 | username=one |
84 | password=two | |
85 | -- | |
86 | verbatim: get | |
73aafe9b JK |
87 | verbatim: protocol=http |
88 | verbatim: host=example.com | |
abca927d JK |
89 | EOF |
90 | ' | |
91 | ||
92 | test_expect_success 'credential_fill continues through partial response' ' | |
93 | check fill "verbatim one \"\"" "verbatim two three" <<-\EOF | |
73aafe9b JK |
94 | protocol=http |
95 | host=example.com | |
abca927d | 96 | -- |
73aafe9b JK |
97 | protocol=http |
98 | host=example.com | |
abca927d JK |
99 | username=two |
100 | password=three | |
101 | -- | |
102 | verbatim: get | |
73aafe9b JK |
103 | verbatim: protocol=http |
104 | verbatim: host=example.com | |
abca927d | 105 | verbatim: get |
73aafe9b JK |
106 | verbatim: protocol=http |
107 | verbatim: host=example.com | |
abca927d JK |
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 | -- | |
2d6dc182 MM |
118 | protocol=ftp |
119 | host=example.com | |
120 | path=foo.git | |
abca927d JK |
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 | |
73aafe9b JK |
133 | protocol=http |
134 | host=example.com | |
abca927d JK |
135 | username=foo |
136 | password=bar | |
137 | -- | |
138 | -- | |
139 | useless: store | |
73aafe9b JK |
140 | useless: protocol=http |
141 | useless: host=example.com | |
abca927d JK |
142 | useless: username=foo |
143 | useless: password=bar | |
144 | verbatim: store | |
73aafe9b JK |
145 | verbatim: protocol=http |
146 | verbatim: host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
154 | protocol=http |
155 | host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
165 | protocol=http |
166 | host=example.com | |
abca927d JK |
167 | username=foo |
168 | password=bar | |
169 | -- | |
170 | -- | |
171 | useless: erase | |
73aafe9b JK |
172 | useless: protocol=http |
173 | useless: host=example.com | |
abca927d JK |
174 | useless: username=foo |
175 | useless: password=bar | |
176 | verbatim: erase | |
73aafe9b JK |
177 | verbatim: protocol=http |
178 | verbatim: host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
186 | protocol=http |
187 | host=example.com | |
abca927d JK |
188 | username=one |
189 | -- | |
73aafe9b JK |
190 | protocol=http |
191 | host=example.com | |
abca927d JK |
192 | username=one |
193 | password=three | |
194 | -- | |
195 | verbatim: get | |
73aafe9b JK |
196 | verbatim: protocol=http |
197 | verbatim: host=example.com | |
abca927d JK |
198 | verbatim: username=one |
199 | EOF | |
200 | ' | |
201 | ||
202 | test_expect_success 'usernames can be overridden' ' | |
203 | check fill "verbatim two three" <<-\EOF | |
73aafe9b JK |
204 | protocol=http |
205 | host=example.com | |
abca927d JK |
206 | username=one |
207 | -- | |
73aafe9b JK |
208 | protocol=http |
209 | host=example.com | |
abca927d JK |
210 | username=two |
211 | password=three | |
212 | -- | |
213 | verbatim: get | |
73aafe9b JK |
214 | verbatim: protocol=http |
215 | verbatim: host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
222 | protocol=http |
223 | host=example.com | |
abca927d JK |
224 | username=one |
225 | password=two | |
226 | -- | |
73aafe9b JK |
227 | protocol=http |
228 | host=example.com | |
abca927d JK |
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 | |
73aafe9b JK |
240 | protocol=http |
241 | host=example.com | |
abca927d | 242 | -- |
73aafe9b JK |
243 | protocol=http |
244 | host=example.com | |
abca927d JK |
245 | username=askpass-username |
246 | password=askpass-password | |
247 | -- | |
73aafe9b JK |
248 | askpass: Username for '\''http://example.com'\'': |
249 | askpass: Password for '\''http://askpass-username@example.com'\'': | |
abca927d JK |
250 | EOF |
251 | ' | |
252 | ||
253 | test_expect_success 'internal getpass does not ask for known username' ' | |
254 | check fill <<-\EOF | |
73aafe9b JK |
255 | protocol=http |
256 | host=example.com | |
abca927d JK |
257 | username=foo |
258 | -- | |
73aafe9b JK |
259 | protocol=http |
260 | host=example.com | |
abca927d JK |
261 | username=foo |
262 | password=askpass-password | |
263 | -- | |
73aafe9b | 264 | askpass: Password for '\''http://foo@example.com'\'': |
abca927d JK |
265 | EOF |
266 | ' | |
267 | ||
11825072 JK |
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 | |
73aafe9b JK |
276 | protocol=http |
277 | host=example.com | |
11825072 | 278 | -- |
73aafe9b JK |
279 | protocol=http |
280 | host=example.com | |
11825072 JK |
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 | -- | |
2d6dc182 MM |
294 | protocol=https |
295 | host=example.com | |
11825072 JK |
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 | -- | |
2d6dc182 MM |
308 | protocol=https |
309 | host=bar | |
11825072 JK |
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 | ||
d5742425 JK |
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 | -- | |
2d6dc182 MM |
324 | protocol=https |
325 | host=example.com | |
d5742425 JK |
326 | username=foo |
327 | password=askpass-password | |
328 | -- | |
329 | askpass: Password for '\''https://foo@example.com'\'': | |
330 | EOF | |
331 | ' | |
332 | ||
a78fbb4f JK |
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 | -- | |
2d6dc182 MM |
339 | protocol=https |
340 | host=example.com | |
a78fbb4f JK |
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 | -- | |
2d6dc182 MM |
354 | protocol=https |
355 | host=example.com | |
356 | path=foo.git | |
a78fbb4f JK |
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 | ||
59b38652 JK |
367 | test_expect_success 'helpers can abort the process' ' |
368 | test_must_fail git \ | |
a88dbd2f | 369 | -c credential.helper=quit \ |
59b38652 | 370 | -c credential.helper="verbatim foo bar" \ |
73aafe9b JK |
371 | credential fill >stdout 2>stderr <<-\EOF && |
372 | protocol=http | |
373 | host=example.com | |
374 | EOF | |
59b38652 | 375 | >expect && |
a88dbd2f JK |
376 | test_cmp expect stdout && |
377 | cat >expect <<-\EOF && | |
378 | quit: get | |
73aafe9b JK |
379 | quit: protocol=http |
380 | quit: host=example.com | |
a88dbd2f JK |
381 | fatal: credential helper '\''quit'\'' told us to quit |
382 | EOF | |
383 | test_i18ncmp expect stderr | |
59b38652 JK |
384 | ' |
385 | ||
24321375 JK |
386 | test_expect_success 'empty helper spec resets helper list' ' |
387 | test_config credential.helper "verbatim file file" && | |
388 | check fill "" "verbatim cmdline cmdline" <<-\EOF | |
73aafe9b JK |
389 | protocol=http |
390 | host=example.com | |
24321375 | 391 | -- |
73aafe9b JK |
392 | protocol=http |
393 | host=example.com | |
24321375 JK |
394 | username=cmdline |
395 | password=cmdline | |
396 | -- | |
397 | verbatim: get | |
73aafe9b JK |
398 | verbatim: protocol=http |
399 | verbatim: host=example.com | |
24321375 JK |
400 | EOF |
401 | ' | |
402 | ||
8ba8ed56 JK |
403 | test_expect_success 'url parser rejects embedded newlines' ' |
404 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
9a6bbee8 | 405 | url=https://one.example.com?%0ahost=two.example.com/ |
8ba8ed56 JK |
406 | EOF |
407 | cat >expect <<-\EOF && | |
c716fe4b JK |
408 | warning: url contains a newline in its host component: https://one.example.com?%0ahost=two.example.com/ |
409 | warning: skipping credential lookup for url: https://one.example.com?%0ahost=two.example.com/ | |
8ba8ed56 | 410 | fatal: refusing to work with credential missing host field |
9a6bbee8 | 411 | EOF |
8ba8ed56 | 412 | test_i18ncmp expect stderr |
9a6bbee8 JK |
413 | ' |
414 | ||
24036686 JK |
415 | test_expect_success 'host-less URLs are parsed as empty host' ' |
416 | check fill "verbatim foo bar" <<-\EOF | |
417 | url=cert:///path/to/cert.pem | |
418 | -- | |
419 | protocol=cert | |
420 | host= | |
421 | path=path/to/cert.pem | |
422 | username=foo | |
423 | password=bar | |
424 | -- | |
425 | verbatim: get | |
426 | verbatim: protocol=cert | |
427 | verbatim: host= | |
428 | verbatim: path=path/to/cert.pem | |
429 | EOF | |
430 | ' | |
431 | ||
8ba8ed56 JK |
432 | test_expect_success 'credential system refuses to work with missing host' ' |
433 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
434 | protocol=http | |
435 | EOF | |
436 | cat >expect <<-\EOF && | |
437 | fatal: refusing to work with credential missing host field | |
438 | EOF | |
439 | test_i18ncmp expect stderr | |
440 | ' | |
441 | ||
442 | test_expect_success 'credential system refuses to work with missing protocol' ' | |
443 | test_must_fail git credential fill 2>stderr <<-\EOF && | |
444 | host=example.com | |
445 | EOF | |
446 | cat >expect <<-\EOF && | |
447 | fatal: refusing to work with credential missing protocol field | |
448 | EOF | |
449 | test_i18ncmp expect stderr | |
450 | ' | |
451 | ||
abca927d | 452 | test_done |