1#!/bin/sh
2
3# Try a set of credential helpers; the expected stdin,
4# stdout and stderr should be provided on stdin,
5# separated by "--".
6check() {
7 credential_opts=
8 credential_cmd=$1
9 shift
10 for arg in "$@"; do
11 credential_opts="$credential_opts -c credential.helper='$arg'"
12 done
13 read_chunk >stdin &&
14 read_chunk >expect-stdout &&
15 read_chunk >expect-stderr &&
16 if ! eval "git $credential_opts credential $credential_cmd <stdin >stdout 2>stderr"; then
17 echo "git credential failed with code $?" &&
18 cat stderr &&
19 false
20 fi &&
21 test_cmp expect-stdout stdout &&
22 test_cmp expect-stderr stderr
23}
24
25read_chunk() {
26 while read line; do
27 case "$line" in
28 --) break ;;
29 *) echo "$line" ;;
30 esac
31 done
32}
33
34# Clear any residual data from previous tests. We only
35# need this when testing third-party helpers which read and
36# write outside of our trash-directory sandbox.
37#
38# Don't bother checking for success here, as it is
39# outside the scope of tests and represents a best effort to
40# clean up after ourselves.
41helper_test_clean() {
42 reject $1 https example.com store-user
43 reject $1 https example.com user1
44 reject $1 https example.com user2
45 reject $1 http path.tld user
46 reject $1 https timeout.tld user
47 reject $1 https sso.tld
48}
49
50reject() {
51 (
52 echo protocol=$2
53 echo host=$3
54 echo username=$4
55 ) | git -c credential.helper=$1 credential reject
56}
57
58helper_test() {
59 HELPER=$1
60
61 test_expect_success "helper ($HELPER) has no existing data" '
62 check fill $HELPER <<-\EOF
63 protocol=https
64 host=example.com
65 --
66 protocol=https
67 host=example.com
68 username=askpass-username
69 password=askpass-password
70 --
71 askpass: Username for '\''https://example.com'\'':
72 askpass: Password for '\''https://askpass-username@example.com'\'':
73 EOF
74 '
75
76 test_expect_success "helper ($HELPER) stores password" '
77 check approve $HELPER <<-\EOF
78 protocol=https
79 host=example.com
80 username=store-user
81 password=store-pass
82 EOF
83 '
84
85 test_expect_success "helper ($HELPER) can retrieve password" '
86 check fill $HELPER <<-\EOF
87 protocol=https
88 host=example.com
89 --
90 protocol=https
91 host=example.com
92 username=store-user
93 password=store-pass
94 --
95 EOF
96 '
97
98 test_expect_success "helper ($HELPER) requires matching protocol" '
99 check fill $HELPER <<-\EOF
100 protocol=http
101 host=example.com
102 --
103 protocol=http
104 host=example.com
105 username=askpass-username
106 password=askpass-password
107 --
108 askpass: Username for '\''http://example.com'\'':
109 askpass: Password for '\''http://askpass-username@example.com'\'':
110 EOF
111 '
112
113 test_expect_success "helper ($HELPER) requires matching host" '
114 check fill $HELPER <<-\EOF
115 protocol=https
116 host=other.tld
117 --
118 protocol=https
119 host=other.tld
120 username=askpass-username
121 password=askpass-password
122 --
123 askpass: Username for '\''https://other.tld'\'':
124 askpass: Password for '\''https://askpass-username@other.tld'\'':
125 EOF
126 '
127
128 test_expect_success "helper ($HELPER) requires matching username" '
129 check fill $HELPER <<-\EOF
130 protocol=https
131 host=example.com
132 username=other
133 --
134 protocol=https
135 host=example.com
136 username=other
137 password=askpass-password
138 --
139 askpass: Password for '\''https://other@example.com'\'':
140 EOF
141 '
142
143 test_expect_success "helper ($HELPER) requires matching path" '
144 test_config credential.usehttppath true &&
145 check approve $HELPER <<-\EOF &&
146 protocol=http
147 host=path.tld
148 path=foo.git
149 username=user
150 password=pass
151 EOF
152 check fill $HELPER <<-\EOF
153 protocol=http
154 host=path.tld
155 path=bar.git
156 --
157 protocol=http
158 host=path.tld
159 path=bar.git
160 username=askpass-username
161 password=askpass-password
162 --
163 askpass: Username for '\''http://path.tld/bar.git'\'':
164 askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
165 EOF
166 '
167
168 test_expect_success "helper ($HELPER) can forget host" '
169 check reject $HELPER <<-\EOF &&
170 protocol=https
171 host=example.com
172 EOF
173 check fill $HELPER <<-\EOF
174 protocol=https
175 host=example.com
176 --
177 protocol=https
178 host=example.com
179 username=askpass-username
180 password=askpass-password
181 --
182 askpass: Username for '\''https://example.com'\'':
183 askpass: Password for '\''https://askpass-username@example.com'\'':
184 EOF
185 '
186
187 test_expect_success "helper ($HELPER) can store multiple users" '
188 check approve $HELPER <<-\EOF &&
189 protocol=https
190 host=example.com
191 username=user1
192 password=pass1
193 EOF
194 check approve $HELPER <<-\EOF &&
195 protocol=https
196 host=example.com
197 username=user2
198 password=pass2
199 EOF
200 check fill $HELPER <<-\EOF &&
201 protocol=https
202 host=example.com
203 username=user1
204 --
205 protocol=https
206 host=example.com
207 username=user1
208 password=pass1
209 EOF
210 check fill $HELPER <<-\EOF
211 protocol=https
212 host=example.com
213 username=user2
214 --
215 protocol=https
216 host=example.com
217 username=user2
218 password=pass2
219 EOF
220 '
221
222 test_expect_success "helper ($HELPER) can forget user" '
223 check reject $HELPER <<-\EOF &&
224 protocol=https
225 host=example.com
226 username=user1
227 EOF
228 check fill $HELPER <<-\EOF
229 protocol=https
230 host=example.com
231 username=user1
232 --
233 protocol=https
234 host=example.com
235 username=user1
236 password=askpass-password
237 --
238 askpass: Password for '\''https://user1@example.com'\'':
239 EOF
240 '
241
242 test_expect_success "helper ($HELPER) remembers other user" '
243 check fill $HELPER <<-\EOF
244 protocol=https
245 host=example.com
246 username=user2
247 --
248 protocol=https
249 host=example.com
250 username=user2
251 password=pass2
252 EOF
253 '
254
255 test_expect_success "helper ($HELPER) can store empty username" '
256 check approve $HELPER <<-\EOF &&
257 protocol=https
258 host=sso.tld
259 username=
260 password=
261 EOF
262 check fill $HELPER <<-\EOF
263 protocol=https
264 host=sso.tld
265 --
266 protocol=https
267 host=sso.tld
268 username=
269 password=
270 EOF
271 '
272}
273
274helper_test_timeout() {
275 HELPER="$*"
276
277 test_expect_success "helper ($HELPER) times out" '
278 check approve "$HELPER" <<-\EOF &&
279 protocol=https
280 host=timeout.tld
281 username=user
282 password=pass
283 EOF
284 sleep 2 &&
285 check fill "$HELPER" <<-\EOF
286 protocol=https
287 host=timeout.tld
288 --
289 protocol=https
290 host=timeout.tld
291 username=askpass-username
292 password=askpass-password
293 --
294 askpass: Username for '\''https://timeout.tld'\'':
295 askpass: Password for '\''https://askpass-username@timeout.tld'\'':
296 EOF
297 '
298}
299
300write_script askpass <<\EOF
301echo >&2 askpass: $*
302what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
303echo "askpass-$what"
304EOF
305GIT_ASKPASS="$PWD/askpass"
306export GIT_ASKPASS