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"