github.com/google/go-github/v57@v57.0.0/test/integration/authorizations_test.go (about)

     1  // Copyright 2016 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  //go:build integration
     7  // +build integration
     8  
     9  package integration
    10  
    11  import (
    12  	"context"
    13  	"os"
    14  	"strings"
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/google/go-github/v57/github"
    19  )
    20  
    21  const msgEnvMissing = "Skipping test because the required environment variable (%v) is not present."
    22  const envKeyClientID = "GITHUB_CLIENT_ID"
    23  const envKeyClientSecret = "GITHUB_CLIENT_SECRET"
    24  const envKeyAccessToken = "GITHUB_ACCESS_TOKEN"
    25  const InvalidTokenValue = "iamnotacroken"
    26  
    27  // TestAuthorizationsAppOperations tests the application/token related operations, such
    28  // as creating, testing, resetting and revoking application OAuth tokens.
    29  func TestAuthorizationsAppOperations(t *testing.T) {
    30  	appAuthenticatedClient := getOAuthAppClient(t)
    31  
    32  	// We know these vars are set because getOAuthAppClient would have
    33  	// skipped the test by now
    34  	clientID := os.Getenv(envKeyClientID)
    35  	accessToken := os.Getenv(envKeyAccessToken)
    36  
    37  	// Verify the token
    38  	appAuth, resp, err := appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, accessToken)
    39  	failOnError(t, err)
    40  	failIfNotStatusCode(t, resp, 200)
    41  
    42  	// Quick sanity check
    43  	if *appAuth.Token != accessToken {
    44  		t.Fatal("The returned auth/token does not match.")
    45  	}
    46  
    47  	// Let's verify that we get a 404 for a non-existent token
    48  	_, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, InvalidTokenValue)
    49  	if err == nil {
    50  		t.Fatal("An error should have been returned because of the invalid token.")
    51  	}
    52  	failIfNotStatusCode(t, resp, 404)
    53  
    54  	// Let's reset the token
    55  	resetAuth, resp, err := appAuthenticatedClient.Authorizations.Reset(context.Background(), clientID, accessToken)
    56  	failOnError(t, err)
    57  	failIfNotStatusCode(t, resp, 200)
    58  
    59  	// Let's verify that we get a 404 for a non-existent token
    60  	_, resp, err = appAuthenticatedClient.Authorizations.Reset(context.Background(), clientID, InvalidTokenValue)
    61  	if err == nil {
    62  		t.Fatal("An error should have been returned because of the invalid token.")
    63  	}
    64  	failIfNotStatusCode(t, resp, 404)
    65  
    66  	// Verify that the token has changed
    67  	if *resetAuth.Token == accessToken {
    68  		t.Fatal("The reset token should be different from the original.")
    69  	}
    70  
    71  	// Verify that we do have a token value
    72  	if *resetAuth.Token == "" {
    73  		t.Fatal("A token value should have been returned.")
    74  	}
    75  
    76  	// Verify that the original token is now invalid
    77  	_, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, accessToken)
    78  	if err == nil {
    79  		t.Fatal("The original token should be invalid.")
    80  	}
    81  	failIfNotStatusCode(t, resp, 404)
    82  
    83  	// Check that the reset token is valid
    84  	_, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, *resetAuth.Token)
    85  	failOnError(t, err)
    86  	failIfNotStatusCode(t, resp, 200)
    87  
    88  	// Let's revoke the token
    89  	resp, err = appAuthenticatedClient.Authorizations.Revoke(context.Background(), clientID, *resetAuth.Token)
    90  	failOnError(t, err)
    91  	failIfNotStatusCode(t, resp, 204)
    92  
    93  	// Sleep for two seconds... I've seen cases where the revocation appears not
    94  	// to have take place immediately.
    95  	time.Sleep(time.Second * 2)
    96  
    97  	// Now, the reset token should also be invalid
    98  	_, resp, err = appAuthenticatedClient.Authorizations.Check(context.Background(), clientID, *resetAuth.Token)
    99  	if err == nil {
   100  		t.Fatal("The reset token should be invalid.")
   101  	}
   102  	failIfNotStatusCode(t, resp, 404)
   103  }
   104  
   105  // failOnError invokes t.Fatal() if err is present.
   106  func failOnError(t *testing.T, err error) {
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  }
   111  
   112  // failIfNotStatusCode invokes t.Fatal() if the response's status code doesn't match the expected code.
   113  func failIfNotStatusCode(t *testing.T, resp *github.Response, expectedCode int) {
   114  	if resp.StatusCode != expectedCode {
   115  		t.Fatalf("Expected HTTP status code [%v] but received [%v]", expectedCode, resp.StatusCode)
   116  	}
   117  }
   118  
   119  // getOAuthAppClient returns a GitHub client for authorization testing. The client
   120  // uses BasicAuth, but instead of username and password, it uses the client id
   121  // and client secret passed in via environment variables
   122  // (and will skip the calling test if those vars are not present). Certain API operations (check
   123  // an authorization; reset an authorization; revoke an authorization for an app)
   124  // require this authentication mechanism.
   125  //
   126  // See GitHub API docs: https://developer.com/v3/oauth_authorizations/#check-an-authorization
   127  func getOAuthAppClient(t *testing.T) *github.Client {
   128  	username, ok := os.LookupEnv(envKeyClientID)
   129  	if !ok {
   130  		t.Skipf(msgEnvMissing, envKeyClientID)
   131  	}
   132  
   133  	password, ok := os.LookupEnv(envKeyClientSecret)
   134  	if !ok {
   135  		t.Skipf(msgEnvMissing, envKeyClientSecret)
   136  	}
   137  
   138  	tp := github.BasicAuthTransport{
   139  		Username: strings.TrimSpace(username),
   140  		Password: strings.TrimSpace(password),
   141  	}
   142  
   143  	return github.NewClient(tp.Client())
   144  }