go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/tokenserver/appengine/impl/projectscope/rpc_mint_project_token_test.go (about) 1 // Copyright 2019 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 projectscope 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "go.opentelemetry.io/otel/trace" 23 24 "go.chromium.org/luci/appengine/gaetesting" 25 "go.chromium.org/luci/auth/identity" 26 "go.chromium.org/luci/common/clock/testclock" 27 "go.chromium.org/luci/common/logging" 28 "go.chromium.org/luci/common/testing/assertions" 29 "go.chromium.org/luci/server/auth" 30 "go.chromium.org/luci/server/auth/authtest" 31 "go.chromium.org/luci/server/auth/signing/signingtest" 32 "go.chromium.org/luci/tokenserver/api/minter/v1" 33 "go.chromium.org/luci/tokenserver/appengine/impl/utils/projectidentity" 34 35 . "github.com/smartystreets/goconvey/convey" 36 ) 37 38 var ( 39 authorizedGroups = []string{projectActorsGroup} 40 testingRequestID = trace.TraceID{1, 2, 3, 4, 5} 41 ) 42 43 func testMintAccessToken(ctx context.Context, params auth.MintAccessTokenParams) (*auth.Token, error) { 44 return &auth.Token{ 45 Token: "", 46 Expiry: time.Now().UTC(), 47 }, nil 48 } 49 50 func testingContext(caller identity.Identity) context.Context { 51 ctx := gaetesting.TestingContext() 52 ctx = logging.SetLevel(ctx, logging.Debug) 53 ctx = trace.ContextWithSpanContext(ctx, trace.NewSpanContext(trace.SpanContextConfig{ 54 TraceID: testingRequestID, 55 })) 56 ctx, _ = testclock.UseTime(ctx, testclock.TestTimeUTC) 57 return auth.WithState(ctx, &authtest.FakeState{ 58 Identity: caller, 59 IdentityGroups: authorizedGroups, 60 }) 61 62 } 63 64 func newTestMintProjectTokenRPC() *MintProjectTokenRPC { 65 rpc := MintProjectTokenRPC{ 66 Signer: signingtest.NewSigner(nil), 67 MintAccessToken: testMintAccessToken, 68 ProjectIdentities: projectidentity.ProjectIdentities, 69 } 70 return &rpc 71 } 72 73 func TestMintProjectToken(t *testing.T) { 74 75 t.Parallel() 76 ctx := testingContext("service@example.com") 77 member, err := auth.IsMember(ctx, projectActorsGroup) 78 79 Convey("initialize rpc handler", t, func() { 80 rpc := newTestMintProjectTokenRPC() 81 82 Convey("validateRequest works", func() { 83 84 Convey("empty fields", func() { 85 req := &minter.MintProjectTokenRequest{ 86 LuciProject: "", 87 OauthScope: []string{}, 88 MinValidityDuration: 7200, 89 } 90 _, err := rpc.MintProjectToken(ctx, req) 91 So(err, ShouldNotBeNil) 92 }) 93 94 Convey("empty project", func() { 95 96 req := &minter.MintProjectTokenRequest{ 97 LuciProject: "", 98 OauthScope: []string{"https://www.googleapis.com/auth/cloud-platform"}, 99 MinValidityDuration: 1800, 100 } 101 _, err := rpc.MintProjectToken(ctx, req) 102 So(err, assertions.ShouldErrLike, `luci_project is empty`) 103 }) 104 105 Convey("empty scopes", func() { 106 107 req := &minter.MintProjectTokenRequest{ 108 LuciProject: "foo-project", 109 OauthScope: []string{}, 110 MinValidityDuration: 1800, 111 } 112 113 _, err := rpc.MintProjectToken(ctx, req) 114 So(err, assertions.ShouldErrLike, `oauth_scope is required`) 115 }) 116 117 Convey("returns nil for valid request", func() { 118 req := &minter.MintProjectTokenRequest{ 119 LuciProject: "test-project", 120 OauthScope: []string{"https://www.googleapis.com/auth/cloud-platform"}, 121 MinValidityDuration: 3600, 122 } 123 _, err := rpc.MintProjectToken(ctx, req) 124 So(err, assertions.ShouldErrLike, "min_validity_duration must not exceed 1800") 125 }) 126 }) 127 128 Convey("MintProjectToken does not return errors with valid input", func() { 129 So(err, ShouldBeNil) 130 So(member, ShouldBeTrue) 131 132 identity, err := rpc.ProjectIdentities(ctx).Create( 133 ctx, 134 &projectidentity.ProjectIdentity{Project: "service-project", Email: "foo@bar.com"}) 135 So(err, ShouldBeNil) 136 So(identity, ShouldNotBeNil) 137 138 req := &minter.MintProjectTokenRequest{ 139 LuciProject: "service-project", 140 OauthScope: []string{"https://www.googleapis.com/auth/cloud-platform"}, 141 } 142 resp, err := rpc.MintProjectToken(ctx, req) 143 So(err, ShouldBeNil) 144 So(resp, ShouldNotBeNil) 145 146 }) 147 148 }) 149 150 }