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