Merge branch 'pw/post-commit-from-sequencer'
[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         test_cmp expect-stdout stdout &&
22         test_cmp expect-stderr stderr
23 }
24
25 read_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.
41 helper_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
50 reject() {
51         (
52                 echo protocol=$2
53                 echo host=$3
54                 echo username=$4
55         ) | git -c credential.helper=$1 credential reject
56 }
57
58 helper_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
274 helper_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
300 write_script askpass <<\EOF
301 echo >&2 askpass: $*
302 what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
303 echo "askpass-$what"
304 EOF
305 GIT_ASKPASS="$PWD/askpass"
306 export GIT_ASKPASS