github.com/google/go-github/v60@v60.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/v60/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 }