github.com/google/go-github/v68@v68.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 8 package integration 9 10 import ( 11 "context" 12 "os" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/google/go-github/v68/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 }