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