go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/teams/rpc/status_test.go (about) 1 // Copyright 2024 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 rpc 16 17 import ( 18 "context" 19 "testing" 20 21 "google.golang.org/grpc/codes" 22 23 "go.chromium.org/luci/server/auth" 24 "go.chromium.org/luci/server/auth/authtest" 25 "go.chromium.org/luci/server/caching" 26 "go.chromium.org/luci/server/secrets" 27 "go.chromium.org/luci/server/secrets/testsecrets" 28 29 "go.chromium.org/luci/teams/internal/teams" 30 "go.chromium.org/luci/teams/internal/testutil" 31 pb "go.chromium.org/luci/teams/proto/v1" 32 33 . "github.com/smartystreets/goconvey/convey" 34 . "go.chromium.org/luci/common/testing/assertions" 35 ) 36 37 func TestTeams(t *testing.T) { 38 Convey("With a Teams server", t, func() { 39 ctx := testutil.IntegrationTestContext(t) 40 ctx = caching.WithEmptyProcessCache(ctx) 41 42 // For user identification. 43 ctx = authtest.MockAuthConfig(ctx) 44 authState := &authtest.FakeState{ 45 Identity: "user:someone@example.com", 46 IdentityGroups: []string{"luci-teams-access"}, 47 } 48 ctx = auth.WithState(ctx, authState) 49 ctx = secrets.Use(ctx, &testsecrets.Store{}) 50 51 server := NewTeamsServer() 52 Convey("Get", func() { 53 Convey("Anonymous rejected", func() { 54 ctx = fakeAuth().anonymous().setInContext(ctx) 55 56 request := &pb.GetTeamRequest{ 57 Name: "teams/1234567890abcdef1234567890abcdef", 58 } 59 status, err := server.Get(ctx, request) 60 61 So(err, ShouldBeRPCPermissionDenied, "log in") 62 So(status, ShouldBeNil) 63 }) 64 Convey("Users without app access rejected", func() { 65 ctx = fakeAuth().setInContext(ctx) 66 67 request := &pb.GetTeamRequest{ 68 Name: "teams/1234567890abcdef1234567890abcdef", 69 } 70 status, err := server.Get(ctx, request) 71 72 So(err, ShouldBeRPCPermissionDenied, "not a member of luci-teams-access") 73 So(status, ShouldBeNil) 74 }) 75 Convey("Read team that exists", func() { 76 ctx = fakeAuth().withAppAccess().setInContext(ctx) 77 78 t, err := teams.NewTeamBuilder().WithID("1234567890abcdef1234567890abcdef").CreateInDB(ctx) 79 So(err, ShouldBeNil) 80 81 request := &pb.GetTeamRequest{ 82 Name: "teams/1234567890abcdef1234567890abcdef", 83 } 84 team, err := server.Get(ctx, request) 85 86 So(err, ShouldBeNil) 87 So(team.Name, ShouldEqual, "teams/1234567890abcdef1234567890abcdef") 88 So(team.CreateTime.AsTime(), ShouldEqual, t.CreateTime) 89 }) 90 Convey("Read own team", func() { 91 ctx = fakeAuth().withAppAccess().setInContext(ctx) 92 93 request := &pb.GetTeamRequest{ 94 Name: "teams/my", 95 } 96 _, err := server.Get(ctx, request) 97 98 So(err, ShouldHaveRPCCode, codes.Unimplemented) 99 }) 100 Convey("Read of invalid id", func() { 101 ctx = fakeAuth().withAppAccess().setInContext(ctx) 102 103 request := &pb.GetTeamRequest{ 104 Name: "teams/INVALID", 105 } 106 _, err := server.Get(ctx, request) 107 108 So(err, ShouldBeRPCInvalidArgument, "name: expected format") 109 }) 110 Convey("Read of non existing valid id", func() { 111 ctx = fakeAuth().withAppAccess().setInContext(ctx) 112 113 request := &pb.GetTeamRequest{ 114 Name: "teams/abcd1234abcd1234abcd1234abcd1234", 115 } 116 _, err := server.Get(ctx, request) 117 118 So(err, ShouldBeRPCNotFound, "team was not found") 119 }) 120 }) 121 }) 122 123 } 124 125 type fakeAuthBuilder struct { 126 state *authtest.FakeState 127 } 128 129 func fakeAuth() *fakeAuthBuilder { 130 return &fakeAuthBuilder{ 131 state: &authtest.FakeState{ 132 Identity: "user:someone@example.com", 133 IdentityGroups: []string{}, 134 }, 135 } 136 } 137 func (a *fakeAuthBuilder) anonymous() *fakeAuthBuilder { 138 a.state.Identity = "anonymous:anonymous" 139 return a 140 } 141 func (a *fakeAuthBuilder) withAppAccess() *fakeAuthBuilder { 142 a.state.IdentityGroups = append(a.state.IdentityGroups, teamsAccessGroup) 143 return a 144 } 145 func (a *fakeAuthBuilder) setInContext(ctx context.Context) context.Context { 146 if a.state.Identity == "anonymous:anonymous" && len(a.state.IdentityGroups) > 0 { 147 panic("You cannot call any of the with methods on fakeAuthBuilder if you call the anonymous method") 148 } 149 return auth.WithState(ctx, a.state) 150 }