go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/auth_service/impl/authdb_test.go (about) 1 // Copyright 2021 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 impl 16 17 import ( 18 "context" 19 "testing" 20 21 "google.golang.org/protobuf/proto" 22 23 "go.chromium.org/luci/gae/impl/memory" 24 "go.chromium.org/luci/gae/service/datastore" 25 "go.chromium.org/luci/server/auth/authdb" 26 "go.chromium.org/luci/server/auth/realms" 27 "go.chromium.org/luci/server/auth/service/protocol" 28 29 "go.chromium.org/luci/auth_service/impl/model" 30 "go.chromium.org/luci/auth_service/internal/permissions" 31 32 . "github.com/smartystreets/goconvey/convey" 33 ) 34 35 var ( 36 testPerm1 = realms.RegisterPermission("testing.tests.perm1") 37 testPerm2 = realms.RegisterPermission("testing.tests.perm2") 38 ) 39 40 func makeTestPermissions(names ...string) []*protocol.Permission { 41 perms := make([]*protocol.Permission, len(names)) 42 for i, name := range names { 43 perms[i] = &protocol.Permission{Name: name} 44 } 45 return perms 46 } 47 48 func TestAuthDBProvider(t *testing.T) { 49 t.Setenv(model.DryRunCronRealmsEnvVar, "false") 50 51 Convey("AuthDBProvider works", t, func() { 52 ctx := memory.Use(context.Background()) 53 authDB := &AuthDBProvider{} 54 55 putRev := func(rev int64, members []string) { 56 err := datastore.RunInTransaction(ctx, func(ctx context.Context) error { 57 globals := &model.AuthGlobalConfig{} 58 state := &model.AuthReplicationState{ 59 AuthDBRev: rev, 60 Parent: model.RootKey(ctx), 61 } 62 group := &model.AuthGroup{ 63 ID: "test-group", 64 Parent: model.RootKey(ctx), 65 Members: members, 66 } 67 realmsGlobals := &model.AuthRealmsGlobals{ 68 Kind: "AuthRealmsGlobals", 69 ID: "globals", 70 Parent: model.RootKey(ctx), 71 PermissionsList: &permissions.PermissionsList{ 72 Permissions: makeTestPermissions(testPerm1.String(), testPerm2.String()), 73 }, 74 } 75 // Grant all members of test-group testPerm2 permission 76 // in project "test-project" root realm. 77 marshalled, marshalErr := proto.Marshal(&protocol.Realms{ 78 Permissions: makeTestPermissions(testPerm2.String()), 79 Realms: []*protocol.Realm{ 80 { 81 Name: "test-project:@root", 82 Bindings: []*protocol.Binding{ 83 { 84 Permissions: []uint32{0}, 85 Principals: []string{"group:test-group"}, 86 }, 87 }, 88 }, 89 }, 90 }) 91 So(marshalErr, ShouldBeNil) 92 projectRealms := &model.AuthProjectRealms{ 93 Kind: "AuthProjectRealms", 94 ID: "test-project", 95 Parent: model.RootKey(ctx), 96 Realms: marshalled, 97 } 98 return datastore.Put(ctx, globals, state, group, realmsGlobals, projectRealms) 99 }, nil) 100 So(err, ShouldBeNil) 101 } 102 103 // Initial revision. 104 putRev(1000, []string{"user:a@example.com"}) 105 106 // Got it. 107 db1, err := authDB.GetAuthDB(ctx) 108 So(err, ShouldBeNil) 109 So(authdb.Revision(db1), ShouldEqual, 1000) 110 111 // Works. 112 yes, err := db1.IsMember(ctx, "user:a@example.com", []string{"test-group"}) 113 So(err, ShouldBeNil) 114 So(yes, ShouldBeTrue) 115 116 // Check permission which hasn't been granted. 117 allowed, err := db1.HasPermission(ctx, "user:a@example.com", testPerm1, "test-project:@root", nil) 118 So(err, ShouldBeNil) 119 So(allowed, ShouldBeFalse) 120 // Check permission which has been granted. 121 allowed, err = db1.HasPermission(ctx, "user:a@example.com", testPerm2, "test-project:@root", nil) 122 So(err, ShouldBeNil) 123 So(allowed, ShouldBeTrue) 124 // Check realms fall back to @root. 125 allowed, err = db1.HasPermission(ctx, "user:a@example.com", testPerm2, "test-project:unknown", nil) 126 So(err, ShouldBeNil) 127 So(allowed, ShouldBeTrue) 128 129 // Calling again returns the exact same object. 130 db2, err := authDB.GetAuthDB(ctx) 131 So(err, ShouldBeNil) 132 So(db2, ShouldEqual, db1) 133 134 // Updated. 135 putRev(1001, nil) 136 137 // Got the new one. 138 db3, err := authDB.GetAuthDB(ctx) 139 So(err, ShouldBeNil) 140 So(authdb.Revision(db3), ShouldEqual, 1001) 141 142 // The group there is updated too. 143 yes, err = db3.IsMember(ctx, "user:a@example.com", []string{"test-group"}) 144 So(err, ShouldBeNil) 145 So(yes, ShouldBeFalse) 146 147 // Check permission which hasn't been granted, as the member is 148 // no longer in the group. 149 allowed, err = db3.HasPermission(ctx, "user:a@example.com", testPerm2, "test-project:@root", nil) 150 So(err, ShouldBeNil) 151 So(allowed, ShouldBeFalse) 152 }) 153 }