]>
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 | |
3d9f5b67 | 25 | write_script git-credential-verbatim <<-\EOF && |
abca927d JK |
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 | |
abca927d JK |
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 | -- | |
2d6dc182 MM |
85 | protocol=ftp |
86 | host=example.com | |
87 | path=foo.git | |
abca927d JK |
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 | ||
11825072 JK |
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 | -- | |
2d6dc182 MM |
219 | protocol=https |
220 | host=example.com | |
11825072 JK |
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 | -- | |
2d6dc182 MM |
233 | protocol=https |
234 | host=bar | |
11825072 JK |
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 | ||
588c70e1 | 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 | ||
d5742425 JK |
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 | -- | |
2d6dc182 MM |
300 | protocol=https |
301 | host=example.com | |
d5742425 JK |
302 | username=foo |
303 | password=askpass-password | |
304 | -- | |
305 | askpass: Password for '\''https://foo@example.com'\'': | |
306 | EOF | |
307 | ' | |
308 | ||
588c70e1 | 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 | ||
82eb2498 | 347 | test_expect_success 'last matching username wins' ' |
588c70e1 | 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 | ||
a78fbb4f JK |
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 | -- | |
2d6dc182 MM |
372 | protocol=https |
373 | host=example.com | |
a78fbb4f JK |
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 | -- | |
2d6dc182 MM |
387 | protocol=https |
388 | host=example.com | |
389 | path=foo.git | |
a78fbb4f JK |
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 | ||
46fd7b39 | 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 | ||
59b38652 JK |
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 && | |
d3c6751b | 425 | test_must_be_empty stdout |
59b38652 JK |
426 | ' |
427 | ||
24321375 JK |
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 | ||
c716fe4b JK |
439 | test_expect_success 'url parser ignores embedded newlines' ' |
440 | check fill <<-EOF | |
9a6bbee8 | 441 | url=https://one.example.com?%0ahost=two.example.com/ |
c716fe4b JK |
442 | -- |
443 | username=askpass-username | |
444 | password=askpass-password | |
445 | -- | |
446 | warning: url contains a newline in its host component: https://one.example.com?%0ahost=two.example.com/ | |
447 | warning: skipping credential lookup for url: https://one.example.com?%0ahost=two.example.com/ | |
448 | askpass: Username: | |
449 | askpass: Password: | |
9a6bbee8 JK |
450 | EOF |
451 | ' | |
452 | ||
abca927d | 453 | test_done |