Merge branch 'rs/grep-function-context' into next
[git] / t / t0300-credentials.sh
1 #!/bin/sh
2
3 test_description='basic credential helper tests'
4 . ./test-lib.sh
5
6 # Try a set of credential helpers; the expected
7 # stdout and stderr should be provided on stdin,
8 # separated by "--".
9 check() {
10         while read line; do
11                 case "$line" in
12                 --) break ;;
13                 *) echo "$line" ;;
14                 esac
15         done >expect-stdout &&
16         cat >expect-stderr &&
17         test-credential "$@" >stdout 2>stderr &&
18         test_cmp expect-stdout stdout &&
19         test_cmp expect-stderr stderr
20 }
21
22 test_expect_success 'setup helper scripts' '
23         cat >dump <<-\EOF &&
24         whoami=$1; shift
25         if test $# = 0; then
26                 echo >&2 "$whoami: <empty>"
27         else
28                 for i in "$@"; do
29                         echo >&2 "$whoami: $i"
30                 done
31         fi
32         EOF
33         chmod +x dump &&
34
35         cat >git-credential-useless <<-\EOF &&
36         #!/bin/sh
37         dump useless "$@"
38         exit 0
39         EOF
40         chmod +x git-credential-useless &&
41
42         cat >git-credential-verbatim <<-\EOF &&
43         #!/bin/sh
44         user=$1; shift
45         pass=$1; shift
46         dump verbatim "$@"
47         test -z "$user" || echo username=$user
48         test -z "$pass" || echo password=$pass
49         EOF
50         chmod +x git-credential-verbatim &&
51
52         cat >askpass <<-\EOF &&
53         #!/bin/sh
54         echo >&2 askpass: $*
55         echo askpass-result
56         EOF
57         chmod +x askpass &&
58         GIT_ASKPASS=askpass &&
59         export GIT_ASKPASS &&
60
61         PATH="$PWD:$PATH"
62 '
63
64 test_expect_success 'credential_fill invokes helper' '
65         check "verbatim foo bar" <<-\EOF
66         username=foo
67         password=bar
68         --
69         verbatim: <empty>
70         EOF
71 '
72
73 test_expect_success 'credential_fill invokes multiple helpers' '
74         check useless "verbatim foo bar" <<-\EOF
75         username=foo
76         password=bar
77         --
78         useless: <empty>
79         verbatim: <empty>
80         EOF
81 '
82
83 test_expect_success 'credential_fill stops when we get a full response' '
84         check "verbatim one two" "verbatim three four" <<-\EOF
85         username=one
86         password=two
87         --
88         verbatim: <empty>
89         EOF
90 '
91
92 test_expect_success 'credential_fill continues through partial response' '
93         check "verbatim one \"\"" "verbatim two three" <<-\EOF
94         username=two
95         password=three
96         --
97         verbatim: <empty>
98         verbatim: --username=one
99         EOF
100 '
101
102 test_expect_success 'credential_fill passes along metadata' '
103         check --description=foo --unique=bar "verbatim one two" <<-\EOF
104         username=one
105         password=two
106         --
107         verbatim: --description=foo
108         verbatim: --unique=bar
109         EOF
110 '
111
112 test_expect_success 'credential_reject calls all helpers' '
113         check --reject --username=foo useless "verbatim one two" <<-\EOF
114         --
115         useless: --reject
116         useless: --username=foo
117         verbatim: --reject
118         verbatim: --username=foo
119         EOF
120 '
121
122 test_expect_success 'do not bother rejecting empty credential' '
123         check --reject useless <<-\EOF
124         --
125         EOF
126 '
127
128 test_expect_success 'usernames can be preserved' '
129         check --username=one "verbatim \"\" three" <<-\EOF
130         username=one
131         password=three
132         --
133         verbatim: --username=one
134 '
135
136 test_expect_success 'usernames can be overridden' '
137         check --username=one "verbatim two three" <<-\EOF
138         username=two
139         password=three
140         --
141         verbatim: --username=one
142         EOF
143 '
144
145 test_expect_success 'do not bother completing already-full credential' '
146         check --username=one --password=two "verbatim three four" <<-\EOF
147         username=one
148         password=two
149         --
150         EOF
151 '
152
153 # We can't test the basic terminal password prompt here because
154 # getpass() tries too hard to find the real terminal. But if our
155 # askpass helper is run, we know the internal getpass is working.
156 test_expect_success 'empty methods falls back to internal getpass' '
157         check <<-\EOF
158         username=askpass-result
159         password=askpass-result
160         --
161         askpass: Username:
162         askpass: Password:
163         EOF
164 '
165
166 test_expect_success 'internal getpass does not ask for known username' '
167         check --username=foo <<-\EOF
168         username=foo
169         password=askpass-result
170         --
171         askpass: Password:
172         EOF
173 '
174
175 test_expect_success 'internal getpass can pull from config' '
176         git config credential.foo.username configured-username
177         check --unique=foo <<-\EOF
178         username=configured-username
179         password=askpass-result
180         --
181         askpass: Password:
182         EOF
183 '
184
185 test_expect_success 'credential-cache caches password' '
186         test_when_finished "git credential-cache --exit" &&
187         check --unique=host cache <<-\EOF &&
188         username=askpass-result
189         password=askpass-result
190         --
191         askpass: Username:
192         askpass: Password:
193         EOF
194         check --unique=host cache <<-\EOF
195         username=askpass-result
196         password=askpass-result
197         --
198         EOF
199 '
200
201 test_expect_success 'credential-cache requires matching unique token' '
202         test_when_finished "git credential-cache --exit" &&
203         check --unique=host cache <<-\EOF &&
204         username=askpass-result
205         password=askpass-result
206         --
207         askpass: Username:
208         askpass: Password:
209         EOF
210         check --unique=host2 cache <<-\EOF
211         username=askpass-result
212         password=askpass-result
213         --
214         askpass: Username:
215         askpass: Password:
216         EOF
217 '
218
219 test_expect_success 'credential-cache requires matching usernames' '
220         test_when_finished "git credential-cache --exit" &&
221         check --unique=host cache <<-\EOF &&
222         username=askpass-result
223         password=askpass-result
224         --
225         askpass: Username:
226         askpass: Password:
227         EOF
228         check --unique=host --username=other cache <<-\EOF
229         username=other
230         password=askpass-result
231         --
232         askpass: Password:
233         EOF
234 '
235
236 test_expect_success 'credential-cache times out' '
237         test_when_finished "git credential-cache --exit || true" &&
238         check --unique=host "cache --timeout=1" <<-\EOF &&
239         username=askpass-result
240         password=askpass-result
241         --
242         askpass: Username:
243         askpass: Password:
244         EOF
245         sleep 2 &&
246         check --unique=host cache <<-\EOF
247         username=askpass-result
248         password=askpass-result
249         --
250         askpass: Username:
251         askpass: Password:
252         EOF
253 '
254
255 test_expect_success 'credential-cache removes rejected credentials' '
256         test_when_finished "git credential-cache --exit || true" &&
257         check --unique=host cache <<-\EOF &&
258         username=askpass-result
259         password=askpass-result
260         --
261         askpass: Username:
262         askpass: Password:
263         EOF
264         check --reject --unique=host --username=askpass-result cache <<-\EOF &&
265         --
266         EOF
267         check --unique=host cache <<-\EOF
268         username=askpass-result
269         password=askpass-result
270         --
271         askpass: Username:
272         askpass: Password:
273         EOF
274 '
275
276 test_expect_success 'credential-store stores password' '
277         test_when_finished "rm -f .git-credentials" &&
278         check --unique=host store <<-\EOF &&
279         username=askpass-result
280         password=askpass-result
281         --
282         askpass: Username:
283         askpass: Password:
284         EOF
285         check --unique=host store <<-\EOF
286         username=askpass-result
287         password=askpass-result
288         --
289         EOF
290 '
291
292 test_expect_success 'credential-store requires matching unique token' '
293         test_when_finished "rm -f .git-credentials" &&
294         check --unique=host store <<-\EOF &&
295         username=askpass-result
296         password=askpass-result
297         --
298         askpass: Username:
299         askpass: Password:
300         EOF
301         check --unique=host2 store <<-\EOF
302         username=askpass-result
303         password=askpass-result
304         --
305         askpass: Username:
306         askpass: Password:
307         EOF
308 '
309
310 test_expect_success 'credential-store removes rejected credentials' '
311         test_when_finished "rm -f .git-credentials" &&
312         check --unique=host store <<-\EOF &&
313         username=askpass-result
314         password=askpass-result
315         --
316         askpass: Username:
317         askpass: Password:
318         EOF
319         check --reject --unique=host --username=askpass-result store <<-\EOF &&
320         --
321         EOF
322         check --unique=host store <<-\EOF
323         username=askpass-result
324         password=askpass-result
325         --
326         askpass: Username:
327         askpass: Password:
328         EOF
329 '
330
331 test_done