go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/auth/integration/gsutil/gsutil_test.go (about) 1 // Copyright 2017 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gsutil 16 17 import ( 18 "bufio" 19 "context" 20 "encoding/json" 21 "io/ioutil" 22 "net/http" 23 "net/url" 24 "os" 25 "strings" 26 "testing" 27 "time" 28 29 "golang.org/x/oauth2" 30 31 "go.chromium.org/luci/common/clock" 32 "go.chromium.org/luci/common/clock/testclock" 33 34 . "github.com/smartystreets/goconvey/convey" 35 ) 36 37 func TestProtocol(t *testing.T) { 38 t.Parallel() 39 40 ctx := context.Background() 41 ctx, _ = testclock.UseTime(ctx, testclock.TestRecentTimeUTC) 42 43 Convey("With server", t, func(c C) { 44 stateDir, err := ioutil.TempDir("", "gsutil_auth") 45 So(err, ShouldBeNil) 46 defer os.RemoveAll(stateDir) 47 48 s := Server{ 49 Source: oauth2.StaticTokenSource(&oauth2.Token{ 50 AccessToken: "tok1", 51 Expiry: clock.Now(ctx).Add(30 * time.Minute), 52 }), 53 StateDir: stateDir, 54 } 55 botoPath, err := s.Start(ctx) 56 So(err, ShouldBeNil) 57 defer s.Stop(ctx) 58 59 // Parse generate .boto file. 60 f, err := os.Open(botoPath) 61 So(err, ShouldBeNil) 62 defer f.Close() 63 boto := map[string]string{} 64 scanner := bufio.NewScanner(f) 65 for scanner.Scan() { 66 chunks := strings.Split(scanner.Text(), "=") 67 if len(chunks) == 2 { 68 boto[strings.TrimSpace(chunks[0])] = strings.TrimSpace(chunks[1]) 69 } 70 } 71 72 call := func(refreshTok string) (*http.Response, error) { 73 form := url.Values{} 74 form.Add("grant_type", "refresh_token") 75 form.Add("refresh_token", refreshTok) 76 form.Add("client_id", "fake_client_id") 77 form.Add("client_secret", "fake_client_secret") 78 return http.Post(boto["provider_token_uri"], "application/x-www-form-urlencoded", strings.NewReader(form.Encode())) 79 } 80 81 Convey("Happy path", func() { 82 resp, err := call(boto["gs_oauth2_refresh_token"]) 83 So(err, ShouldBeNil) 84 defer resp.Body.Close() 85 tok := map[string]any{} 86 So(resp.StatusCode, ShouldEqual, 200) 87 So(resp.Header.Get("Content-Type"), ShouldEqual, "application/json") 88 So(json.NewDecoder(resp.Body).Decode(&tok), ShouldBeNil) 89 So(tok, ShouldResemble, map[string]any{ 90 "access_token": "tok1", 91 "expires_in": 1800.0, 92 "token_type": "Bearer", 93 }) 94 }) 95 96 Convey("Bad refresh token", func() { 97 resp, err := call("bad-refresh-token") 98 So(err, ShouldBeNil) 99 defer resp.Body.Close() 100 So(resp.StatusCode, ShouldEqual, 400) 101 }) 102 }) 103 }