Merge branch 'jk/init-core-worktree-at-root'
[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 }
48
49 reject() {
50         (
51                 echo protocol=$2
52                 echo host=$3
53                 echo username=$4
54         ) | git -c credential.helper=$1 credential reject
55 }
56
57 helper_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
255 helper_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
281 write_script askpass <<\EOF
282 echo >&2 askpass: $*
283 what=$(echo $1 | cut -d" " -f1 | tr A-Z a-z | tr -cd a-z)
284 echo "askpass-$what"
285 EOF
286 GIT_ASKPASS="$PWD/askpass"
287 export GIT_ASKPASS