github.com/scorpionis/hub@v2.2.1+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 'socket' 9 require 'etc' 10 machine_id = "#{Etc.getlogin}@#{Socket.gethostname}" 11 12 post('/authorizations') { 13 assert_basic_auth 'mislav', 'kitty' 14 assert :scopes => ['repo'], 15 :note => "hub for #{machine_id}", 16 :note_url => 'http://hub.github.com/' 17 json :token => 'OTOKEN' 18 } 19 get('/user') { 20 halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' 21 json :login => 'MiSlAv' 22 } 23 post('/user/repos') { 24 halt 401 unless request.env['HTTP_AUTHORIZATION'] == 'token OTOKEN' 25 json :full_name => 'mislav/dotfiles' 26 } 27 """ 28 When I run `hub create` interactively 29 When I type "mislav" 30 And I type "kitty" 31 Then the output should contain "github.com username:" 32 And the output should contain "github.com password for mislav (never stored):" 33 And the exit status should be 0 34 And the file "../home/.config/hub" should contain "user: MiSlAv" 35 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 36 And the file "../home/.config/hub" should have mode "0600" 37 38 Scenario: Rename & retry creating authorization if there's a token name collision 39 Given the GitHub API server: 40 """ 41 require 'socket' 42 require 'etc' 43 machine_id = "#{Etc.getlogin}@#{Socket.gethostname}" 44 45 post('/authorizations') { 46 assert_basic_auth 'mislav', 'kitty' 47 if params[:note] == "hub for #{machine_id} 3" 48 json :token => 'OTOKEN' 49 else 50 status 422 51 json :message => 'Validation Failed', 52 :errors => [{ 53 :resource => 'OauthAccess', 54 :code => 'already_exists', 55 :field => 'description' 56 }] 57 end 58 } 59 get('/user') { 60 json :login => 'MiSlAv' 61 } 62 post('/user/repos') { 63 json :full_name => 'mislav/dotfiles' 64 } 65 """ 66 When I run `hub create` interactively 67 When I type "mislav" 68 And I type "kitty" 69 Then the output should contain "github.com username:" 70 And the exit status should be 0 71 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 72 73 Scenario: Avoid getting caught up in infinite recursion while retrying token names 74 Given the GitHub API server: 75 """ 76 tries = 0 77 post('/authorizations') { 78 tries += 1 79 halt 400, json(:message => "too many tries") if tries >= 10 80 status 422 81 json :message => 'Validation Failed', 82 :errors => [{ 83 :resource => 'OauthAccess', 84 :code => 'already_exists', 85 :field => 'description' 86 }] 87 } 88 """ 89 When I run `hub create` interactively 90 When I type "mislav" 91 And I type "kitty" 92 Then the output should contain: 93 """ 94 Error creating repository: Unprocessable Entity (HTTP 422) 95 Duplicate value for "description" 96 """ 97 And the exit status should be 1 98 And the file "../home/.config/hub" should not exist 99 100 Scenario: Credentials from GITHUB_USER & GITHUB_PASSWORD 101 Given the GitHub API server: 102 """ 103 post('/authorizations') { 104 assert_basic_auth 'mislav', 'kitty' 105 json :token => 'OTOKEN' 106 } 107 get('/user') { 108 json :login => 'mislav' 109 } 110 post('/user/repos') { 111 json :full_name => 'mislav/dotfiles' 112 } 113 """ 114 Given $GITHUB_USER is "mislav" 115 And $GITHUB_PASSWORD is "kitty" 116 When I successfully run `hub create` 117 Then the output should not contain "github.com password for mislav" 118 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 119 120 Scenario: Wrong password 121 Given the GitHub API server: 122 """ 123 post('/authorizations') { 124 assert_basic_auth 'mislav', 'kitty' 125 } 126 """ 127 When I run `hub create` interactively 128 When I type "mislav" 129 And I type "WRONG" 130 Then the stderr should contain exactly: 131 """ 132 Error creating repository: Unauthorized (HTTP 401) 133 Bad credentials 134 135 """ 136 And the exit status should be 1 137 And the file "../home/.config/hub" should not exist 138 139 Scenario: Personal access token used instead of password 140 Given the GitHub API server: 141 """ 142 post('/authorizations') { 143 status 403 144 json :message => "This API can only be accessed with username and password Basic Auth" 145 } 146 """ 147 When I run `hub create` interactively 148 When I type "mislav" 149 And I type "PERSONALACCESSTOKEN" 150 Then the stderr should contain exactly: 151 """ 152 Error creating repository: Forbidden (HTTP 403) 153 This API can only be accessed with username and password Basic Auth 154 155 """ 156 And the exit status should be 1 157 And the file "../home/.config/hub" should not exist 158 159 Scenario: Two-factor authentication, create authorization 160 Given the GitHub API server: 161 """ 162 post('/authorizations') { 163 assert_basic_auth 'mislav', 'kitty' 164 if request.env['HTTP_X_GITHUB_OTP'] == '112233' 165 json :token => 'OTOKEN' 166 else 167 response.headers['X-GitHub-OTP'] = 'required; app' 168 status 401 169 json :message => "Must specify two-factor authentication OTP code." 170 end 171 } 172 get('/user') { 173 json :login => 'mislav' 174 } 175 post('/user/repos') { 176 json :full_name => 'mislav/dotfiles' 177 } 178 """ 179 When I run `hub create` interactively 180 When I type "mislav" 181 And I type "kitty" 182 And I type "112233" 183 Then the output should contain "github.com password for mislav (never stored):" 184 Then the output should contain "two-factor authentication code:" 185 And the output should not contain "warning: invalid two-factor code" 186 And the exit status should be 0 187 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 188 189 Scenario: Retry entering two-factor authentication code 190 Given the GitHub API server: 191 """ 192 previous_otp_code = nil 193 post('/authorizations') { 194 assert_basic_auth 'mislav', 'kitty' 195 if request.env['HTTP_X_GITHUB_OTP'] == '112233' 196 halt 400 unless '666' == previous_otp_code 197 json :token => 'OTOKEN' 198 else 199 previous_otp_code = request.env['HTTP_X_GITHUB_OTP'] 200 response.headers['X-GitHub-OTP'] = 'required; app' 201 status 401 202 json :message => "Must specify two-factor authentication OTP code." 203 end 204 } 205 get('/user') { 206 json :login => 'mislav' 207 } 208 post('/user/repos') { 209 json :full_name => 'mislav/dotfiles' 210 } 211 """ 212 When I run `hub create` interactively 213 When I type "mislav" 214 And I type "kitty" 215 And I type "666" 216 And I type "112233" 217 Then the output should contain "warning: invalid two-factor code" 218 And the exit status should be 0 219 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 220 221 Scenario: Special characters in username & password 222 Given the GitHub API server: 223 """ 224 post('/authorizations') { 225 assert_basic_auth 'mislav@example.com', 'my pass@phrase ok?' 226 json :token => 'OTOKEN' 227 } 228 get('/user') { 229 json :login => 'mislav' 230 } 231 get('/repos/mislav/dotfiles') { status 200 } 232 """ 233 When I run `hub create` interactively 234 When I type "mislav@example.com" 235 And I type "my pass@phrase ok?" 236 Then the output should contain "github.com password for mislav@example.com (never stored):" 237 And the exit status should be 0 238 And the file "../home/.config/hub" should contain "user: mislav" 239 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 240 241 Scenario: Enterprise fork authentication with username & password, re-using existing authorization 242 Given the GitHub API server: 243 """ 244 require 'rack/auth/basic' 245 post('/api/v3/authorizations', :host_name => 'git.my.org') { 246 auth = Rack::Auth::Basic::Request.new(env) 247 halt 401 unless auth.credentials == %w[mislav kitty] 248 json :token => 'OTOKEN', :note_url => 'http://hub.github.com/' 249 } 250 get('/api/v3/user', :host_name => 'git.my.org') { 251 json :login => 'mislav' 252 } 253 post('/api/v3/repos/evilchelu/dotfiles/forks', :host_name => 'git.my.org') { '' } 254 """ 255 And "git.my.org" is a whitelisted Enterprise host 256 And the "origin" remote has url "git@git.my.org:evilchelu/dotfiles.git" 257 When I run `hub fork` interactively 258 And I type "mislav" 259 And I type "kitty" 260 Then the output should contain "git.my.org password for mislav (never stored):" 261 And the exit status should be 0 262 And the file "../home/.config/hub" should contain "git.my.org" 263 And the file "../home/.config/hub" should contain "user: mislav" 264 And the file "../home/.config/hub" should contain "oauth_token: OTOKEN" 265 And the url for "mislav" should be "git@git.my.org:mislav/dotfiles.git"