-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Expand file tree
/
Copy pathauthentication.feature
More file actions
531 lines (507 loc) · 19 KB
/
Copy pathauthentication.feature
File metadata and controls
531 lines (507 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
Feature: OAuth authentication
Background:
Given I am in "dotfiles" git repo
Scenario: Ask for username & password, create authorization
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
assert :scopes => ['repo', 'gist'],
:note_url => 'https://hub.github.com/'
status 201
json :token => 'OTOKEN'
}
get('/user') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :login => 'MiSlAv'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
status 201
json :full_name => 'mislav/dotfiles'
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
Then the output should contain "github.com username:"
And the output should contain "github.com access token with scope 'repo' for mislav (generate one at https://github.com/settings/tokens):"
And the exit status should be 0
And the file "~/.config/hub" should contain "user: MiSlAv"
And the file "~/.config/hub" should contain "oauth_token: OTOKEN"
And the file "~/.config/hub" should have mode "0600"
Scenario: Prompt for username & password, receive personal access token
Given the GitHub API server:
"""
get('/user') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token 0123456789012345678901234567890123456789'
json :login => 'llIMLLib'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token 0123456789012345678901234567890123456789'
status 201
json :full_name => 'llimllib/dotfiles'
}
"""
When I run `hub create` interactively
When I type "llimllib"
And I type "0123456789012345678901234567890123456789"
And the exit status should be 0
And the file "../home/.config/hub" should contain "user: llIMLLib"
And the file "../home/.config/hub" should contain:
"""
oauth_token: "0123456789012345678901234567890123456789"
"""
Scenario: Ask for username & password, receive password that looks like a token
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'llimllib', '0123456789012345678901234567890123456789'
status 201
json :token => 'OTOKEN'
}
get('/user') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
json :login => 'llIMLLib'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
status 201
json :full_name => 'llimllib/dotfiles'
}
"""
When I run `hub create` interactively
When I type "llimllib"
And I type "0123456789012345678901234567890123456789"
And the exit status should be 0
And the file "../home/.config/hub" should contain "user: llIMLLib"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Rename & retry creating authorization if there's a token name collision
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
if params[:note] =~ /\Ahub for .+ 3\Z/
status 201
json :token => 'OTOKEN'
else
status 422
json :message => 'Validation Failed',
:errors => [{
:resource => 'OauthAccess',
:code => 'already_exists',
:field => 'description'
}]
end
}
get('/user') {
json :login => 'MiSlAv'
}
post('/user/repos') {
status 201
json :full_name => 'mislav/dotfiles'
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
Then the output should contain "github.com username:"
And the exit status should be 0
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Avoid getting caught up in infinite recursion while retrying token names
Given the GitHub API server:
"""
tries = 0
post('/authorizations') {
tries += 1
halt 400, json(:message => "too many tries") if tries >= 10
status 422
json :message => 'Validation Failed',
:errors => [{
:resource => 'OauthAccess',
:code => 'already_exists',
:field => 'description'
}]
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
Then the output should contain:
"""
Error creating repository: Unprocessable Entity (HTTP 422)
Duplicate value for "description"
"""
And the exit status should be 1
And the file "../home/.config/hub" should not exist
Scenario: Credentials from GITHUB_USER & GITHUB_PASSWORD
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
status 201
json :token => 'OTOKEN'
}
get('/user') {
json :login => 'mislav'
}
post('/user/repos') {
status 201
json :full_name => 'mislav/dotfiles'
}
"""
Given $GITHUB_USER is "mislav"
And $GITHUB_PASSWORD is "kitty"
When I successfully run `hub create`
Then the output should not contain "github.com access token with scope 'repo' for mislav"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: XDG: legacy config found, credentials from GITHUB_USER & GITHUB_PASSWORD
Given I am "mislav" on github.com with OAuth token "LTOKEN"
And the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
status 201
json :token => 'OTOKEN'
}
get('/user') {
json :login => 'mislav'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
status 201
json :full_name => 'mislav/dotfiles'
}
"""
And $GITHUB_USER is "mislav"
And $GITHUB_PASSWORD is "kitty"
And $XDG_CONFIG_HOME is "$HOME/.xdg"
When I successfully run `hub create`
Then the file "../home/.xdg/hub" should contain "oauth_token: OTOKEN"
And the stderr with expanded variables should contain exactly:
"""
Notice: config file found but not respected at: <$HOME>/.config/hub
You might want to move it to `<$HOME>/.xdg/hub' to avoid re-authenticating.\n
"""
Scenario: XDG: config from secondary directories
Given I am "mislav" on github.com with OAuth token "OTOKEN"
And the GitHub API server:
"""
get('/user') {
json :login => 'mislav'
}
post('/user/repos') {
halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN'
status 201
json :full_name => 'mislav/dotfiles'
}
"""
And $GITHUB_USER is "mislav"
And $GITHUB_PASSWORD is "kitty"
And $XDG_CONFIG_HOME is "$HOME/.xdg"
And $XDG_CONFIG_DIRS is "/etc/xdg-nonsense:$HOME/.xdg-dir"
When I move the file named "../home/.config/hub" to "../home/.xdg-dir/hub"
And I successfully run `hub create`
Then the file "../home/.xdg/hub" should not exist
And the stderr should contain exactly ""
Scenario: Credentials from GITHUB_TOKEN
Given the GitHub API server:
"""
get('/user') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token OTOKEN"
json :login => 'mislav'
}
post('/user/repos') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token OTOKEN"
status 201
json :full_name => 'mislav/dotfiles'
}
"""
Given $GITHUB_TOKEN is "OTOKEN"
When I successfully run `hub create`
Then the output should not contain "github.com password"
And the output should not contain "github.com username"
And the file "../home/.config/hub" should not exist
Scenario: Credentials from GITHUB_TOKEN when obtaining username fails
Given I am in "git://github.com/monalisa/playground.git" git repo
Given the GitHub API server:
"""
get('/user') {
status 403
json :message => "Resource not accessible by integration",
:documentation_url => "https://developer.github.com/v3/users/#get-the-authenticated-user"
}
"""
Given $GITHUB_TOKEN is "OTOKEN"
Given $GITHUB_USER is ""
When I run `hub release show v1.2.0`
Then the output should not contain "github.com password"
And the output should not contain "github.com username"
And the file "../home/.config/hub" should not exist
And the exit status should be 1
And the stderr should contain exactly:
"""
Error getting current user: Forbidden (HTTP 403)
Resource not accessible by integration
You must specify GITHUB_USER via environment variable.\n
"""
Scenario: Credentials from GITHUB_TOKEN and GITHUB_USER
Given I am in "git://github.com/monalisa/playground.git" git repo
Given the GitHub API server:
"""
get('/user') {
status 403
json :message => "Resource not accessible by integration",
:documentation_url => "https://developer.github.com/v3/users/#get-the-authenticated-user"
}
get('/repos/monalisa/playground/releases') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token OTOKEN"
json [
{ tag_name: 'v1.2.0',
}
]
}
"""
Given $GITHUB_TOKEN is "OTOKEN"
Given $GITHUB_USER is "hubot"
When I successfully run `hub release show v1.2.0`
Then the output should not contain "github.com password"
And the output should not contain "github.com username"
And the file "../home/.config/hub" should not exist
Scenario: Credentials from GITHUB_TOKEN and GITHUB_REPOSITORY
Given I am in "git://github.com/monalisa/playground.git" git repo
Given the GitHub API server:
"""
get('/user') {
status 403
json :message => "Resource not accessible by integration",
:documentation_url => "https://developer.github.com/v3/users/#get-the-authenticated-user"
}
get('/repos/monalisa/playground/releases') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token OTOKEN"
json [
{ tag_name: 'v1.2.0',
}
]
}
"""
Given $GITHUB_TOKEN is "OTOKEN"
Given $GITHUB_REPOSITORY is "mona-lisa/play-ground"
Given $GITHUB_USER is ""
When I successfully run `hub release show v1.2.0`
Then the output should not contain "github.com password"
And the output should not contain "github.com username"
And the file "../home/.config/hub" should not exist
Scenario: Credentials from GITHUB_TOKEN override those from config file
Given I am "mislav" on github.com with OAuth token "OTOKEN"
Given the GitHub API server:
"""
get('/user') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token PTOKEN"
json :login => 'parkr'
}
get('/repos/parkr/dotfiles') {
halt 401 unless request.env["HTTP_AUTHORIZATION"] == "token PTOKEN"
json :private => false,
:name => 'dotfiles', :owner => { :login => 'parkr' },
:permissions => { :push => true }
}
"""
Given $GITHUB_TOKEN is "PTOKEN"
When I successfully run `hub clone dotfiles`
Then it should clone "git@github.com:parkr/dotfiles.git"
And the file "../home/.config/hub" should contain "user: mislav"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Wrong password
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "WRONG"
Then the stderr should contain exactly:
"""
Error creating repository: Unauthorized (HTTP 401)
Bad credentials
"""
And the exit status should be 1
And the file "../home/.config/hub" should not exist
Scenario: Two-factor authentication, create authorization
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
if request.env['HTTP_X_GITHUB_OTP'] == '112233'
status 201
json :token => 'OTOKEN'
else
response.headers['X-GitHub-OTP'] = 'required; app'
status 401
json :message => "Must specify two-factor authentication OTP code."
end
}
get('/user') {
json :login => 'mislav'
}
post('/user/repos') {
status 201
json :full_name => 'mislav/dotfiles'
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
And I type "112233"
Then the output should contain "github.com access token with scope 'repo' for mislav (generate one at https://github.com/settings/tokens):"
Then the output should contain "two-factor authentication code:"
And the output should not contain "warning: invalid two-factor code"
And the exit status should be 0
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Retry entering two-factor authentication code
Given the GitHub API server:
"""
previous_otp_code = nil
post('/authorizations') {
assert_basic_auth 'mislav', 'kitty'
if request.env['HTTP_X_GITHUB_OTP'] == '112233'
halt 400 unless '666' == previous_otp_code
status 201
json :token => 'OTOKEN'
else
previous_otp_code = request.env['HTTP_X_GITHUB_OTP']
response.headers['X-GitHub-OTP'] = 'required; app'
status 401
json :message => "Must specify two-factor authentication OTP code."
end
}
get('/user') {
json :login => 'mislav'
}
post('/user/repos') {
status 201
json :full_name => 'mislav/dotfiles'
}
"""
When I run `hub create` interactively
When I type "mislav"
And I type "kitty"
And I type "666"
And I type "112233"
Then the output should contain "warning: invalid two-factor code"
And the exit status should be 0
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Special characters in username & password
Given the GitHub API server:
"""
post('/authorizations') {
assert_basic_auth 'mislav@example.com', 'my pass@phrase ok?'
status 201
json :token => 'OTOKEN'
}
get('/user') {
json :login => 'mislav'
}
get('/repos/mislav/dotfiles') {
json :full_name => 'mislav/dotfiles'
}
"""
When I run `hub create` interactively
When I type "mislav@example.com"
And I type "my pass@phrase ok?"
Then the output should contain "github.com access token with scope 'repo' for mislav@example.com (generate one at https://github.com/settings/tokens):"
And the exit status should be 0
And the file "../home/.config/hub" should contain "user: mislav"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
Scenario: Enterprise fork authentication with username & password, re-using existing authorization
Given the GitHub API server:
"""
require 'rack/auth/basic'
post('/api/v3/authorizations', :host_name => 'git.my.org') {
auth = Rack::Auth::Basic::Request.new(env)
halt 401 unless auth.credentials == %w[mislav kitty]
status 201
json :token => 'OTOKEN', :note_url => 'https://hub.github.com/'
}
get('/api/v3/user', :host_name => 'git.my.org') {
json :login => 'mislav'
}
post('/api/v3/repos/evilchelu/dotfiles/forks', :host_name => 'git.my.org') {
status 202
json :name => 'dotfiles', :owner => { :login => 'mislav' }
}
"""
And "git.my.org" is a whitelisted Enterprise host
And the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git"
When I run `hub fork` interactively
And I type "mislav"
And I type "kitty"
Then the output should contain "git.my.org access token with scope 'repo' for mislav (generate one at https://git.my.org/settings/tokens):"
And the exit status should be 0
And the file "../home/.config/hub" should contain "git.my.org"
And the file "../home/.config/hub" should contain "user: mislav"
And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"
And the url for "mislav" should be "git@git.my.org:mislav/dotfiles.git"
Scenario: Broken config is missing user.
Given a file named "../home/.config/hub" with:
"""
github.com:
- oauth_token: OTOKEN
protocol: https
"""
And the "origin" remote has url "git://github.com/mislav/coral.git"
When I run `hub browse -u` interactively
And I type "pcorpet"
Then the output should contain "github.com username:"
And the file "../home/.config/hub" should contain "- user: pcorpet"
And the file "../home/.config/hub" should contain " oauth_token: OTOKEN"
Scenario: Broken config is missing user and interactive input is empty.
Given a file named "../home/.config/hub" with:
"""
github.com:
- oauth_token: OTOKEN
protocol: https
"""
And the "origin" remote has url "git://github.com/mislav/coral.git"
When I run `hub browse -u` interactively
And I type ""
Then the output should contain "github.com username:"
And the output should contain "missing user"
And the file "../home/.config/hub" should not contain "user"
Scenario: Config file is not writeable, should exit before asking for credentials
Given $HUB_CONFIG is "/InvalidConfigFile"
When I run `hub create` interactively
Then the output should contain:
"""
open /InvalidConfigFile:
"""
And the exit status should be 1
And the file "../home/.config/hub" should not exist
Scenario: Config file is not writeable on default location, should exit before asking for credentials
Given a directory named "../home/.config" with mode "600"
When I run `hub create` interactively
Then the output with expanded variables should contain:
"""
<$HOME>/.config/hub: permission denied\n
"""
And the exit status should be 1
And the file "../home/.config/hub" should not exist
Scenario: GitHub SSO challenge
Given I am "monalisa" on github.com with OAuth token "OTOKEN"
And I am in "git://github.com/acme/playground.git" git repo
Given the GitHub API server:
"""
get('/repos/acme/playground/releases') {
response.headers['X-GitHub-SSO'] = 'required; url=http://example.com?auth=HASH'
status 403
}
"""
When I run `hub release show v1.2.0`
Then the stderr should contain exactly:
"""
Error fetching releases: Forbidden (HTTP 403)
You must authorize your token to access this organization:
http://example.com?auth=HASH\n
"""