]>
Commit | Line | Data |
---|---|---|
f27491d5 JK |
1 | # Shell library for testing credential handling including helpers. See t0302 |
2 | # for an example of testing a specific helper. | |
abca927d JK |
3 | |
4 | # Try a set of credential helpers; the expected stdin, | |
5 | # stdout and stderr should be provided on stdin, | |
6 | # separated by "--". | |
7 | check() { | |
e30b2feb JRI |
8 | credential_opts= |
9 | credential_cmd=$1 | |
10 | shift | |
11 | for arg in "$@"; do | |
12 | credential_opts="$credential_opts -c credential.helper='$arg'" | |
13 | done | |
abca927d JK |
14 | read_chunk >stdin && |
15 | read_chunk >expect-stdout && | |
16 | read_chunk >expect-stderr && | |
e30b2feb JRI |
17 | if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then |
18 | echo "git credential failed with code $?" && | |
19 | cat stderr && | |
20 | false | |
21 | fi && | |
abca927d | 22 | test_cmp expect-stdout stdout && |
1108cea7 | 23 | test_cmp expect-stderr stderr |
abca927d JK |
24 | } |
25 | ||
26 | read_chunk() { | |
27 | while read line; do | |
28 | case "$line" in | |
29 | --) break ;; | |
30 | *) echo "$line" ;; | |
31 | esac | |
32 | done | |
33 | } | |
34 | ||
e2770979 JK |
35 | # Clear any residual data from previous tests. We only |
36 | # need this when testing third-party helpers which read and | |
37 | # write outside of our trash-directory sandbox. | |
38 | # | |
39 | # Don't bother checking for success here, as it is | |
40 | # outside the scope of tests and represents a best effort to | |
41 | # clean up after ourselves. | |
42 | helper_test_clean() { | |
43 | reject $1 https example.com store-user | |
44 | reject $1 https example.com user1 | |
45 | reject $1 https example.com user2 | |
0ce02e2f H |
46 | reject $1 https example.com user-expiry |
47 | reject $1 https example.com user-expiry-overwrite | |
a5c76569 | 48 | reject $1 https example.com user4 |
e2770979 JK |
49 | reject $1 http path.tld user |
50 | reject $1 https timeout.tld user | |
3c90bda6 | 51 | reject $1 https sso.tld |
e2770979 JK |
52 | } |
53 | ||
54 | reject() { | |
55 | ( | |
56 | echo protocol=$2 | |
57 | echo host=$3 | |
58 | echo username=$4 | |
e30b2feb | 59 | ) | git -c credential.helper=$1 credential reject |
e2770979 JK |
60 | } |
61 | ||
62 | helper_test() { | |
63 | HELPER=$1 | |
64 | ||
65 | test_expect_success "helper ($HELPER) has no existing data" ' | |
66 | check fill $HELPER <<-\EOF | |
67 | protocol=https | |
68 | host=example.com | |
69 | -- | |
2d6dc182 MM |
70 | protocol=https |
71 | host=example.com | |
e2770979 JK |
72 | username=askpass-username |
73 | password=askpass-password | |
74 | -- | |
75 | askpass: Username for '\''https://example.com'\'': | |
76 | askpass: Password for '\''https://askpass-username@example.com'\'': | |
77 | EOF | |
78 | ' | |
79 | ||
80 | test_expect_success "helper ($HELPER) stores password" ' | |
81 | check approve $HELPER <<-\EOF | |
82 | protocol=https | |
83 | host=example.com | |
84 | username=store-user | |
85 | password=store-pass | |
86 | EOF | |
87 | ' | |
88 | ||
89 | test_expect_success "helper ($HELPER) can retrieve password" ' | |
90 | check fill $HELPER <<-\EOF | |
91 | protocol=https | |
92 | host=example.com | |
93 | -- | |
2d6dc182 MM |
94 | protocol=https |
95 | host=example.com | |
e2770979 JK |
96 | username=store-user |
97 | password=store-pass | |
98 | -- | |
99 | EOF | |
100 | ' | |
101 | ||
102 | test_expect_success "helper ($HELPER) requires matching protocol" ' | |
103 | check fill $HELPER <<-\EOF | |
104 | protocol=http | |
105 | host=example.com | |
106 | -- | |
2d6dc182 MM |
107 | protocol=http |
108 | host=example.com | |
e2770979 JK |
109 | username=askpass-username |
110 | password=askpass-password | |
111 | -- | |
112 | askpass: Username for '\''http://example.com'\'': | |
113 | askpass: Password for '\''http://askpass-username@example.com'\'': | |
114 | EOF | |
115 | ' | |
116 | ||
117 | test_expect_success "helper ($HELPER) requires matching host" ' | |
118 | check fill $HELPER <<-\EOF | |
119 | protocol=https | |
120 | host=other.tld | |
121 | -- | |
2d6dc182 MM |
122 | protocol=https |
123 | host=other.tld | |
e2770979 JK |
124 | username=askpass-username |
125 | password=askpass-password | |
126 | -- | |
127 | askpass: Username for '\''https://other.tld'\'': | |
128 | askpass: Password for '\''https://askpass-username@other.tld'\'': | |
129 | EOF | |
130 | ' | |
131 | ||
132 | test_expect_success "helper ($HELPER) requires matching username" ' | |
133 | check fill $HELPER <<-\EOF | |
134 | protocol=https | |
135 | host=example.com | |
136 | username=other | |
137 | -- | |
2d6dc182 MM |
138 | protocol=https |
139 | host=example.com | |
e2770979 JK |
140 | username=other |
141 | password=askpass-password | |
142 | -- | |
143 | askpass: Password for '\''https://other@example.com'\'': | |
144 | EOF | |
145 | ' | |
146 | ||
147 | test_expect_success "helper ($HELPER) requires matching path" ' | |
148 | test_config credential.usehttppath true && | |
149 | check approve $HELPER <<-\EOF && | |
150 | protocol=http | |
151 | host=path.tld | |
152 | path=foo.git | |
153 | username=user | |
154 | password=pass | |
155 | EOF | |
156 | check fill $HELPER <<-\EOF | |
157 | protocol=http | |
158 | host=path.tld | |
159 | path=bar.git | |
160 | -- | |
2d6dc182 MM |
161 | protocol=http |
162 | host=path.tld | |
163 | path=bar.git | |
e2770979 JK |
164 | username=askpass-username |
165 | password=askpass-password | |
166 | -- | |
167 | askpass: Username for '\''http://path.tld/bar.git'\'': | |
168 | askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'': | |
169 | EOF | |
170 | ' | |
171 | ||
172 | test_expect_success "helper ($HELPER) can forget host" ' | |
173 | check reject $HELPER <<-\EOF && | |
174 | protocol=https | |
175 | host=example.com | |
176 | EOF | |
177 | check fill $HELPER <<-\EOF | |
178 | protocol=https | |
179 | host=example.com | |
180 | -- | |
2d6dc182 MM |
181 | protocol=https |
182 | host=example.com | |
e2770979 JK |
183 | username=askpass-username |
184 | password=askpass-password | |
185 | -- | |
186 | askpass: Username for '\''https://example.com'\'': | |
187 | askpass: Password for '\''https://askpass-username@example.com'\'': | |
188 | EOF | |
189 | ' | |
190 | ||
191 | test_expect_success "helper ($HELPER) can store multiple users" ' | |
192 | check approve $HELPER <<-\EOF && | |
193 | protocol=https | |
194 | host=example.com | |
195 | username=user1 | |
196 | password=pass1 | |
197 | EOF | |
198 | check approve $HELPER <<-\EOF && | |
199 | protocol=https | |
200 | host=example.com | |
201 | username=user2 | |
202 | password=pass2 | |
203 | EOF | |
204 | check fill $HELPER <<-\EOF && | |
205 | protocol=https | |
206 | host=example.com | |
207 | username=user1 | |
208 | -- | |
2d6dc182 MM |
209 | protocol=https |
210 | host=example.com | |
e2770979 JK |
211 | username=user1 |
212 | password=pass1 | |
213 | EOF | |
214 | check fill $HELPER <<-\EOF | |
215 | protocol=https | |
216 | host=example.com | |
217 | username=user2 | |
218 | -- | |
2d6dc182 MM |
219 | protocol=https |
220 | host=example.com | |
e2770979 JK |
221 | username=user2 |
222 | password=pass2 | |
223 | EOF | |
224 | ' | |
225 | ||
226 | test_expect_success "helper ($HELPER) can forget user" ' | |
227 | check reject $HELPER <<-\EOF && | |
228 | protocol=https | |
229 | host=example.com | |
230 | username=user1 | |
231 | EOF | |
232 | check fill $HELPER <<-\EOF | |
233 | protocol=https | |
234 | host=example.com | |
235 | username=user1 | |
236 | -- | |
2d6dc182 MM |
237 | protocol=https |
238 | host=example.com | |
e2770979 JK |
239 | username=user1 |
240 | password=askpass-password | |
241 | -- | |
242 | askpass: Password for '\''https://user1@example.com'\'': | |
243 | EOF | |
244 | ' | |
245 | ||
246 | test_expect_success "helper ($HELPER) remembers other user" ' | |
247 | check fill $HELPER <<-\EOF | |
248 | protocol=https | |
249 | host=example.com | |
250 | username=user2 | |
251 | -- | |
2d6dc182 MM |
252 | protocol=https |
253 | host=example.com | |
e2770979 JK |
254 | username=user2 |
255 | password=pass2 | |
256 | EOF | |
257 | ' | |
3c90bda6 JB |
258 | |
259 | test_expect_success "helper ($HELPER) can store empty username" ' | |
260 | check approve $HELPER <<-\EOF && | |
261 | protocol=https | |
262 | host=sso.tld | |
263 | username= | |
264 | password= | |
265 | EOF | |
266 | check fill $HELPER <<-\EOF | |
267 | protocol=https | |
268 | host=sso.tld | |
269 | -- | |
270 | protocol=https | |
271 | host=sso.tld | |
272 | username= | |
273 | password= | |
274 | EOF | |
275 | ' | |
71201ab0 TB |
276 | |
277 | : ${GIT_TEST_LONG_CRED_BUFFER:=1024} | |
278 | # 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL | |
279 | LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23)) | |
280 | LONG_VALUE=$(perl -e 'print "a" x shift' $LONG_VALUE_LEN) | |
281 | ||
282 | test_expect_success "helper ($HELPER) not confused by long header" ' | |
283 | check approve $HELPER <<-\EOF && | |
284 | protocol=https | |
285 | host=victim.example.com | |
286 | username=user | |
287 | password=to-be-stolen | |
288 | EOF | |
289 | ||
290 | check fill $HELPER <<-EOF | |
291 | protocol=https | |
292 | host=badguy.example.com | |
293 | wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com | |
294 | -- | |
295 | protocol=https | |
296 | host=badguy.example.com | |
297 | username=askpass-username | |
298 | password=askpass-password | |
299 | wwwauth[]=basic realm=${LONG_VALUE}host=victim.example.com | |
300 | -- | |
301 | askpass: Username for '\''https://badguy.example.com'\'': | |
302 | askpass: Password for '\''https://askpass-username@badguy.example.com'\'': | |
303 | EOF | |
304 | ' | |
e2770979 JK |
305 | } |
306 | ||
307 | helper_test_timeout() { | |
308 | HELPER="$*" | |
309 | ||
310 | test_expect_success "helper ($HELPER) times out" ' | |
311 | check approve "$HELPER" <<-\EOF && | |
312 | protocol=https | |
313 | host=timeout.tld | |
314 | username=user | |
315 | password=pass | |
316 | EOF | |
317 | sleep 2 && | |
318 | check fill "$HELPER" <<-\EOF | |
319 | protocol=https | |
320 | host=timeout.tld | |
321 | -- | |
2d6dc182 MM |
322 | protocol=https |
323 | host=timeout.tld | |
e2770979 JK |
324 | username=askpass-username |
325 | password=askpass-password | |
326 | -- | |
327 | askpass: Username for '\''https://timeout.tld'\'': | |
328 | askpass: Password for '\''https://askpass-username@timeout.tld'\'': | |
329 | EOF | |
330 | ' | |
331 | } | |
abca927d | 332 | |
0ce02e2f H |
333 | helper_test_password_expiry_utc() { |
334 | HELPER=$1 | |
335 | ||
336 | test_expect_success "helper ($HELPER) stores password_expiry_utc" ' | |
337 | check approve $HELPER <<-\EOF | |
338 | protocol=https | |
339 | host=example.com | |
340 | username=user-expiry | |
341 | password=pass | |
342 | password_expiry_utc=9999999999 | |
343 | EOF | |
344 | ' | |
345 | ||
346 | test_expect_success "helper ($HELPER) gets password_expiry_utc" ' | |
347 | check fill $HELPER <<-\EOF | |
348 | protocol=https | |
349 | host=example.com | |
350 | username=user-expiry | |
351 | -- | |
352 | protocol=https | |
353 | host=example.com | |
354 | username=user-expiry | |
355 | password=pass | |
356 | password_expiry_utc=9999999999 | |
357 | -- | |
358 | EOF | |
359 | ' | |
360 | ||
361 | test_expect_success "helper ($HELPER) overwrites when password_expiry_utc changes" ' | |
362 | check approve $HELPER <<-\EOF && | |
363 | protocol=https | |
364 | host=example.com | |
365 | username=user-expiry-overwrite | |
366 | password=pass1 | |
367 | password_expiry_utc=9999999998 | |
368 | EOF | |
369 | check approve $HELPER <<-\EOF && | |
370 | protocol=https | |
371 | host=example.com | |
372 | username=user-expiry-overwrite | |
373 | password=pass2 | |
374 | password_expiry_utc=9999999999 | |
375 | EOF | |
376 | check fill $HELPER <<-\EOF && | |
377 | protocol=https | |
378 | host=example.com | |
379 | username=user-expiry-overwrite | |
380 | -- | |
381 | protocol=https | |
382 | host=example.com | |
383 | username=user-expiry-overwrite | |
384 | password=pass2 | |
385 | password_expiry_utc=9999999999 | |
386 | EOF | |
387 | check reject $HELPER <<-\EOF && | |
388 | protocol=https | |
389 | host=example.com | |
390 | username=user-expiry-overwrite | |
391 | password=pass2 | |
392 | EOF | |
393 | check fill $HELPER <<-\EOF | |
394 | protocol=https | |
395 | host=example.com | |
396 | username=user-expiry-overwrite | |
397 | -- | |
398 | protocol=https | |
399 | host=example.com | |
400 | username=user-expiry-overwrite | |
401 | password=askpass-password | |
402 | -- | |
403 | askpass: Password for '\''https://user-expiry-overwrite@example.com'\'': | |
404 | EOF | |
405 | ' | |
406 | } | |
407 | ||
a5c76569 H |
408 | helper_test_oauth_refresh_token() { |
409 | HELPER=$1 | |
410 | ||
411 | test_expect_success "helper ($HELPER) stores oauth_refresh_token" ' | |
412 | check approve $HELPER <<-\EOF | |
413 | protocol=https | |
414 | host=example.com | |
415 | username=user4 | |
416 | password=pass | |
417 | oauth_refresh_token=xyzzy | |
418 | EOF | |
419 | ' | |
420 | ||
421 | test_expect_success "helper ($HELPER) gets oauth_refresh_token" ' | |
422 | check fill $HELPER <<-\EOF | |
423 | protocol=https | |
424 | host=example.com | |
425 | username=user4 | |
426 | -- | |
427 | protocol=https | |
428 | host=example.com | |
429 | username=user4 | |
430 | password=pass | |
431 | oauth_refresh_token=xyzzy | |
432 | -- | |
433 | EOF | |
434 | ' | |
435 | } | |
436 | ||
c049216f | 437 | write_script askpass <<\EOF |
abca927d | 438 | echo >&2 askpass: $* |
5a435202 | 439 | what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z) |
abca927d JK |
440 | echo "askpass-$what" |
441 | EOF | |
abca927d JK |
442 | GIT_ASKPASS="$PWD/askpass" |
443 | export GIT_ASKPASS |