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"