github.com/trevoraustin/hub@v2.2.0-preview1.0.20141105230840-96d8bfc654cc+incompatible/features/authentication.feature (about) 1 Feature: OAuth authentication 2 Background: 3 Given I am in "dotfiles" git repo 4 5 Scenario: Ask for username & password, create authorization 6 Given the GitHub API server: 7 """ 8 require 'rack/auth/basic' 9 get('/authorizations') { '[]' } 10 post('/authorizations') { 11 auth = Rack::Auth::Basic::Request.new(env) 12 halt 401 unless auth.credentials == %w[mislav kitty] 13 assert :scopes => ['repo'] 14 json :token => 'OTOKEN' 15 } 16 get('/user') { 17 halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' 18 json :login => 'MiSlAv' 19 } 20 post('/user/repos') { 21 halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' 22 json :full_name => 'mislav/dotfiles' 23 } 24 """ 25 When I run `hub create` interactively 26 When I type "mislav" 27 And I type "kitty" 28 Then the output should contain "github.com username:" 29 And the output should contain "github.com password for mislav (never stored):" 30 And the exit status should be 0 31 And the file "../home/.config/hub" should contain "user: MiSlAv" 32 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 33 And the file "../home/.config/hub" should have mode "0600" 34 35 Scenario: Ask for username & password, re-use existing authorization 36 Given the GitHub API server: 37 """ 38 require 'rack/auth/basic' 39 get('/authorizations') { 40 auth = Rack::Auth::Basic::Request.new(env) 41 halt 401 unless auth.credentials == %w[mislav kitty] 42 json [ 43 {:token => 'SKIPPD', :note_url => 'http://example.com'}, 44 {:token => 'OTOKEN', :note_url => 'http://hub.github.com/'} 45 ] 46 } 47 get('/user') { 48 json :login => 'mislav' 49 } 50 post('/user/repos') { 51 json :full_name => 'mislav/dotfiles' 52 } 53 """ 54 When I run `hub create` interactively 55 When I type "mislav" 56 And I type "kitty" 57 Then the output should contain "github.com password for mislav (never stored):" 58 And the exit status should be 0 59 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 60 61 Scenario: Re-use existing authorization with an old URL 62 Given the GitHub API server: 63 """ 64 require 'rack/auth/basic' 65 get('/authorizations') { 66 auth = Rack::Auth::Basic::Request.new(env) 67 halt 401 unless auth.credentials == %w[mislav kitty] 68 json [ 69 {:token => 'OTOKEN', :note => 'hub', :note_url => 'http://defunkt.io/hub/'} 70 ] 71 } 72 post('/authorizations') { 73 status 422 74 json :message => "Validation Failed", 75 :errors => [{:resource => "OauthAccess", :code => "already_exists", :field => "description"}] 76 } 77 get('/user') { 78 json :login => 'mislav' 79 } 80 post('/user/repos') { 81 json :full_name => 'mislav/dotfiles' 82 } 83 """ 84 When I run `hub create` interactively 85 When I type "mislav" 86 And I type "kitty" 87 Then the output should contain "github.com password for mislav (never stored):" 88 And the exit status should be 0 89 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 90 91 Scenario: Re-use existing authorization found on page 3 92 Given the GitHub API server: 93 """ 94 get('/authorizations') { 95 assert_basic_auth 'mislav', 'kitty' 96 page = (params[:page] || 1).to_i 97 if page < 3 98 response.headers['Link'] = %(<#{url}?page=#{page+1}>; rel="next") 99 json [] 100 else 101 json [ 102 {:token => 'OTOKEN', :note => 'hub', :note_url => 'http://hub.github.com/'} 103 ] 104 end 105 } 106 post('/authorizations') { 107 status 422 108 json :message => "Validation Failed", 109 :errors => [{:resource => "OauthAccess", :code => "already_exists", :field => "description"}] 110 } 111 get('/user') { 112 json :login => 'mislav' 113 } 114 post('/user/repos') { 115 json :full_name => 'mislav/dotfiles' 116 } 117 """ 118 When I run `hub create` interactively 119 When I type "mislav" 120 And I type "kitty" 121 Then the output should contain "github.com password for mislav (never stored):" 122 And the exit status should be 0 123 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 124 125 Scenario: Credentials from GITHUB_USER & GITHUB_PASSWORD 126 Given the GitHub API server: 127 """ 128 require 'rack/auth/basic' 129 get('/authorizations') { 130 auth = Rack::Auth::Basic::Request.new(env) 131 halt 401 unless auth.credentials == %w[mislav kitty] 132 json [ 133 {:token => 'OTOKEN', :note_url => 'http://hub.github.com/'} 134 ] 135 } 136 get('/user') { 137 json :login => 'mislav' 138 } 139 post('/user/repos') { 140 json :full_name => 'mislav/dotfiles' 141 } 142 """ 143 Given $GITHUB_USER is "mislav" 144 And $GITHUB_PASSWORD is "kitty" 145 When I successfully run `hub create` 146 Then the output should not contain "github.com password for mislav" 147 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 148 149 Scenario: Wrong password 150 Given the GitHub API server: 151 """ 152 require 'rack/auth/basic' 153 get('/authorizations') { 154 auth = Rack::Auth::Basic::Request.new(env) 155 halt 401 unless auth.credentials == %w[mislav kitty] 156 } 157 """ 158 When I run `hub create` interactively 159 When I type "mislav" 160 And I type "WRONG" 161 Then the stderr should contain "Error creating repository: Unauthorized (HTTP 401)" 162 And the exit status should be 1 163 And the file "../home/.config/hub" should not exist 164 165 Scenario: Two-factor authentication, create authorization 166 Given the GitHub API server: 167 """ 168 require 'rack/auth/basic' 169 get('/authorizations') { 170 auth = Rack::Auth::Basic::Request.new(env) 171 halt 401 unless auth.credentials == %w[mislav kitty] 172 if request.env['HTTP_X_GITHUB_OTP'] != "112233" 173 response.headers['X-GitHub-OTP'] = "required; app" 174 halt 401 175 end 176 json [ ] 177 } 178 post('/authorizations') { 179 auth = Rack::Auth::Basic::Request.new(env) 180 halt 401 unless auth.credentials == %w[mislav kitty] 181 halt 412 unless params[:scopes] 182 if request.env['HTTP_X_GITHUB_OTP'] != "112233" 183 response.headers['X-GitHub-OTP'] = "required; app" 184 halt 401 185 end 186 json :token => 'OTOKEN' 187 } 188 get('/user') { 189 json :login => 'mislav' 190 } 191 post('/user/repos') { 192 json :full_name => 'mislav/dotfiles' 193 } 194 """ 195 When I run `hub create` interactively 196 When I type "mislav" 197 And I type "kitty" 198 And I type "112233" 199 Then the output should contain "github.com password for mislav (never stored):" 200 Then the output should contain "two-factor authentication code:" 201 And the exit status should be 0 202 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 203 204 Scenario: Two-factor authentication, re-use existing authorization 205 Given the GitHub API server: 206 """ 207 token = 'OTOKEN' 208 post('/authorizations') { 209 assert_basic_auth 'mislav', 'kitty' 210 token << 'SMS' 211 status 412 212 } 213 get('/authorizations') { 214 assert_basic_auth 'mislav', 'kitty' 215 if request.env['HTTP_X_GITHUB_OTP'] != "112233" 216 response.headers['X-GitHub-OTP'] = "required; app" 217 halt 401 218 end 219 json [ { 220 :token => token, 221 :note_url => 'http://hub.github.com/' 222 } ] 223 } 224 get('/user') { 225 json :login => 'mislav' 226 } 227 post('/user/repos') { 228 json :full_name => 'mislav/dotfiles' 229 } 230 """ 231 When I run `hub create` interactively 232 When I type "mislav" 233 And I type "kitty" 234 And I type "112233" 235 Then the output should contain "github.com password for mislav (never stored):" 236 Then the output should contain "two-factor authentication code:" 237 And the exit status should be 0 238 And the file "../home/.config/hub" should contain "oauth_token: OTOKENSMS" 239 240 Scenario: Special characters in username & password 241 Given the GitHub API server: 242 """ 243 get('/authorizations') { '[]' } 244 post('/authorizations') { 245 assert_basic_auth 'mislav@example.com', 'my pass@phrase ok?' 246 json :token => 'OTOKEN' 247 } 248 get('/user') { 249 json :login => 'mislav' 250 } 251 get('/repos/mislav/dotfiles') { status 200 } 252 """ 253 When I run `hub create` interactively 254 When I type "mislav@example.com" 255 And I type "my pass@phrase ok?" 256 Then the output should contain "github.com password for mislav@example.com (never stored):" 257 And the exit status should be 0 258 And the file "../home/.config/hub" should contain "user: mislav" 259 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN"