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}
48
49reject() {
50 (
51 echo protocol=$2
52 echo host=$3
53 echo username=$4
54 ) | git -c credential.helper=$1 credential reject
55}
56
57helper_test() {
58 HELPER=$1
59
60 test_expect_success "helper ($HELPER) has no existing data" '
61 check fill $HELPER <<-\EOF
62 protocol=https
63 host=example.com
64 --
65 protocol=https
66 host=example.com
67 username=askpass-username
68 password=askpass-password
69 --
70 askpass: Username for '\''https://example.com'\'':
71 askpass: Password for '\''https://askpass-username@example.com'\'':
72 EOF
73 '
74
75 test_expect_success "helper ($HELPER) stores password" '
76 check approve $HELPER <<-\EOF
77 protocol=https
78 host=example.com
79 username=store-user
80 password=store-pass
81 EOF
82 '
83
84 test_expect_success "helper ($HELPER) can retrieve password" '
85 check fill $HELPER <<-\EOF
86 protocol=https
87 host=example.com
88 --
89 protocol=https
90 host=example.com
91 username=store-user
92 password=store-pass
93 --
94 EOF
95 '
96
97 test_expect_success "helper ($HELPER) requires matching protocol" '
98 check fill $HELPER <<-\EOF
99 protocol=http
100 host=example.com
101 --
102 protocol=http
103 host=example.com
104 username=askpass-username
105 password=askpass-password
106 --
107 askpass: Username for '\''http://example.com'\'':
108 askpass: Password for '\''http://askpass-username@example.com'\'':
109 EOF
110 '
111
112 test_expect_success "helper ($HELPER) requires matching host" '
113 check fill $HELPER <<-\EOF
114 protocol=https
115 host=other.tld
116 --
117 protocol=https
118 host=other.tld
119 username=askpass-username
120 password=askpass-password
121 --
122 askpass: Username for '\''https://other.tld'\'':
123 askpass: Password for '\''https://askpass-username@other.tld'\'':
124 EOF
125 '
126
127 test_expect_success "helper ($HELPER) requires matching username" '
128 check fill $HELPER <<-\EOF
129 protocol=https
130 host=example.com
131 username=other
132 --
133 protocol=https
134 host=example.com
135 username=other
136 password=askpass-password
137 --
138 askpass: Password for '\''https://other@example.com'\'':
139 EOF
140 '
141
142 test_expect_success "helper ($HELPER) requires matching path" '
143 test_config credential.usehttppath true &&
144 check approve $HELPER <<-\EOF &&
145 protocol=http
146 host=path.tld
147 path=foo.git
148 username=user
149 password=pass
150 EOF
151 check fill $HELPER <<-\EOF
152 protocol=http
153 host=path.tld
154 path=bar.git
155 --
156 protocol=http
157 host=path.tld
158 path=bar.git
159 username=askpass-username
160 password=askpass-password
161 --
162 askpass: Username for '\''http://path.tld/bar.git'\'':
163 askpass: Password for '\''http://askpass-username@path.tld/bar.git'\'':
164 EOF
165 '
166
167 test_expect_success "helper ($HELPER) can forget host" '
168 check reject $HELPER <<-\EOF &&
169 protocol=https
170 host=example.com
171 EOF
172 check fill $HELPER <<-\EOF
173 protocol=https
174 host=example.com
175 --
176 protocol=https
177 host=example.com
178 username=askpass-username
179 password=askpass-password
180 --
181 askpass: Username for '\''https://example.com'\'':
182 askpass: Password for '\''https://askpass-username@example.com'\'':
183 EOF
184 '
185
186 test_expect_success "helper ($HELPER) can store multiple users" '
187 check approve $HELPER <<-\EOF &&
188 protocol=https
189 host=example.com
190 username=user1
191 password=pass1
192 EOF
193 check approve $HELPER <<-\EOF &&
194 protocol=https
195 host=example.com
196 username=user2
197 password=pass2
198 EOF
199 check fill $HELPER <<-\EOF &&
200 protocol=https
201 host=example.com
202 username=user1
203 --
204 protocol=https
205 host=example.com
206 username=user1
207 password=pass1
208 EOF
209 check fill $HELPER <<-\EOF
210 protocol=https
211 host=example.com
212 username=user2
213 --
214 protocol=https
215 host=example.com
216 username=user2
217 password=pass2
218 EOF
219 '
220
221 test_expect_success "helper ($HELPER) can forget user" '
222 check reject $HELPER <<-\EOF &&
223 protocol=https
224 host=example.com
225 username=user1
226 EOF
227 check fill $HELPER <<-\EOF
228 protocol=https
229 host=example.com
230 username=user1
231 --
232 protocol=https
233 host=example.com
234 username=user1
235 password=askpass-password
236 --
237 askpass: Password for '\''https://user1@example.com'\'':
238 EOF
239 '
240
241 test_expect_success "helper ($HELPER) remembers other user" '
242 check fill $HELPER <<-\EOF
243 protocol=https
244 host=example.com
245 username=user2
246 --
247 protocol=https
248 host=example.com
249 username=user2
250 password=pass2
251 EOF
252 '
253}
254
255helper_test_timeout() {
256 HELPER="$*"
257
258 test_expect_success "helper ($HELPER) times out" '
259 check approve "$HELPER" <<-\EOF &&
260 protocol=https
261 host=timeout.tld
262 username=user
263 password=pass
264 EOF
265 sleep 2 &&
266 check fill "$HELPER" <<-\EOF
267 protocol=https
268 host=timeout.tld
269 --
270 protocol=https
271 host=timeout.tld
272 username=askpass-username
273 password=askpass-password
274 --
275 askpass: Username for '\''https://timeout.tld'\'':
276 askpass: Password for '\''https://askpass-username@timeout.tld'\'':
277 EOF
278 '
279}
280
281cat >askpass <<\EOF
282#!/bin/sh
283echo >&2 askpass: $*
284what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
285echo "askpass-$what"
286EOF
287chmod +x askpass
288GIT_ASKPASS="$PWD/askpass"
289export GIT_ASKPASS