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