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