Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: appengine/logdog/coordinator/coordinatorTest/context.go

Issue 1971493003: LogDog: Project READ access for user endpoints. (Closed) Base URL: https://github.com/luci/luci-go@logdog-project-service-config
Patch Set: Updated patchset dependency Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package coordinatorTest 5 package coordinatorTest
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "strings"
10 "time"
9 11
10 "github.com/golang/protobuf/proto" 12 "github.com/golang/protobuf/proto"
11 ds "github.com/luci/gae/service/datastore" 13 ds "github.com/luci/gae/service/datastore"
14 "github.com/luci/gae/service/info"
12 "github.com/luci/luci-go/appengine/logdog/coordinator" 15 "github.com/luci/luci-go/appengine/logdog/coordinator"
13 "github.com/luci/luci-go/appengine/logdog/coordinator/config" 16 "github.com/luci/luci-go/appengine/logdog/coordinator/config"
14 "github.com/luci/luci-go/appengine/tumble" 17 "github.com/luci/luci-go/appengine/tumble"
15 "github.com/luci/luci-go/common/clock" 18 "github.com/luci/luci-go/common/clock"
16 "github.com/luci/luci-go/common/clock/testclock" 19 "github.com/luci/luci-go/common/clock/testclock"
17 luciConfig "github.com/luci/luci-go/common/config" 20 luciConfig "github.com/luci/luci-go/common/config"
18 "github.com/luci/luci-go/common/config/impl/memory" 21 "github.com/luci/luci-go/common/config/impl/memory"
19 "github.com/luci/luci-go/common/gcloud/gs" 22 "github.com/luci/luci-go/common/gcloud/gs"
20 "github.com/luci/luci-go/common/logging" 23 "github.com/luci/luci-go/common/logging"
21 "github.com/luci/luci-go/common/logging/gologger" 24 "github.com/luci/luci-go/common/logging/gologger"
22 » configProto "github.com/luci/luci-go/common/proto/config" 25 » "github.com/luci/luci-go/common/proto/google"
23 "github.com/luci/luci-go/common/proto/logdog/svcconfig" 26 "github.com/luci/luci-go/common/proto/logdog/svcconfig"
24 "github.com/luci/luci-go/server/auth" 27 "github.com/luci/luci-go/server/auth"
25 "github.com/luci/luci-go/server/auth/authtest" 28 "github.com/luci/luci-go/server/auth/authtest"
26 "github.com/luci/luci-go/server/logdog/storage" 29 "github.com/luci/luci-go/server/logdog/storage"
27 memoryStorage "github.com/luci/luci-go/server/logdog/storage/memory" 30 memoryStorage "github.com/luci/luci-go/server/logdog/storage/memory"
28 "github.com/luci/luci-go/server/settings" 31 "github.com/luci/luci-go/server/settings"
29 "golang.org/x/net/context" 32 "golang.org/x/net/context"
30 ) 33 )
31 34
32 // Environment contains all of the testing facilities that are installed into 35 // Environment contains all of the testing facilities that are installed into
(...skipping 27 matching lines...) Expand all
60 // default) into Services. 63 // default) into Services.
61 ArchivalPublisher ArchivalPublisher 64 ArchivalPublisher ArchivalPublisher
62 } 65 }
63 66
64 // JoinGroup adds the named group the to the list of groups for the current 67 // JoinGroup adds the named group the to the list of groups for the current
65 // identity. 68 // identity.
66 func (e *Environment) JoinGroup(g string) { 69 func (e *Environment) JoinGroup(g string) {
67 e.AuthState.IdentityGroups = append(e.AuthState.IdentityGroups, g) 70 e.AuthState.IdentityGroups = append(e.AuthState.IdentityGroups, g)
68 } 71 }
69 72
73 // LeaveAllGroups clears all auth groups that the user is currently a member of.
74 func (e *Environment) LeaveAllGroups() {
75 e.AuthState.IdentityGroups = nil
76 e.JoinGroup("all")
77 }
78
70 // ClearCoordinatorConfig removes the Coordinator configuration entry, 79 // ClearCoordinatorConfig removes the Coordinator configuration entry,
71 // simulating a missing config. 80 // simulating a missing config.
72 func (e *Environment) ClearCoordinatorConfig(c context.Context) { 81 func (e *Environment) ClearCoordinatorConfig(c context.Context) {
73 configSet, _ := config.ServiceConfigPath(c) 82 configSet, _ := config.ServiceConfigPath(c)
74 delete(e.Config, configSet) 83 delete(e.Config, configSet)
75 } 84 }
76 85
77 // ModServiceConfig loads the current service configuration, invokes the 86 // ModServiceConfig loads the current service configuration, invokes the
78 // callback with its contents, and writes the result back to config. 87 // callback with its contents, and writes the result back to config.
79 func (e *Environment) ModServiceConfig(c context.Context, fn func(*svcconfig.Coo rdinator)) { 88 func (e *Environment) ModServiceConfig(c context.Context, fn func(*svcconfig.Con fig)) {
80 configSet, configPath := config.ServiceConfigPath(c) 89 configSet, configPath := config.ServiceConfigPath(c)
81 90
82 var cfg svcconfig.Config 91 var cfg svcconfig.Config
83 e.modTextProtobuf(configSet, configPath, &cfg, func() { 92 e.modTextProtobuf(configSet, configPath, &cfg, func() {
84 » » if cfg.Coordinator == nil { 93 » » fn(&cfg)
85 » » » cfg.Coordinator = &svcconfig.Coordinator{}
86 » » }
87 » » fn(cfg.Coordinator)
88 }) 94 })
89 } 95 }
90 96
97 // ModProjectConfig loads the current configuration for the named project,
98 // invokes the callback with its contents, and writes the result back to config.
99 func (e *Environment) ModProjectConfig(c context.Context, proj luciConfig.Projec tName, fn func(*svcconfig.ProjectConfig)) {
100 configSet, configPath := config.ProjectConfigPath(c, proj)
101
102 var pcfg svcconfig.ProjectConfig
103 e.modTextProtobuf(configSet, configPath, &pcfg, func() {
104 fn(&pcfg)
105 })
106 }
107
91 // DrainTumbleAll drains all Tumble instances across all namespaces. 108 // DrainTumbleAll drains all Tumble instances across all namespaces.
92 func (e *Environment) DrainTumbleAll(c context.Context) { 109 func (e *Environment) DrainTumbleAll(c context.Context) {
93 projects, err := luciConfig.Get(c).GetProjects() 110 projects, err := luciConfig.Get(c).GetProjects()
94 if err != nil { 111 if err != nil {
95 panic(err) 112 panic(err)
96 } 113 }
97 114
98 for _, proj := range projects { 115 for _, proj := range projects {
99 WithProjectNamespace(c, luciConfig.ProjectName(proj.ID), func(c context.Context) { 116 WithProjectNamespace(c, luciConfig.ProjectName(proj.ID), func(c context.Context) {
100 e.Tumble.Drain(c) 117 e.Tumble.Drain(c)
(...skipping 11 matching lines...) Expand all
112 } 129 }
113 130
114 case luciConfig.ErrNoConfig: 131 case luciConfig.ErrNoConfig:
115 break 132 break
116 133
117 default: 134 default:
118 panic(err) 135 panic(err)
119 } 136 }
120 137
121 fn() 138 fn()
139 e.addConfigEntry(configSet, path, proto.MarshalTextString(msg))
140 }
122 141
142 func (e *Environment) addConfigEntry(configSet, path, content string) {
123 cset := e.Config[configSet] 143 cset := e.Config[configSet]
124 if cset == nil { 144 if cset == nil {
125 cset = make(map[string]string) 145 cset = make(map[string]string)
126 e.Config[configSet] = cset 146 e.Config[configSet] = cset
127 } 147 }
128 » cset[path] = proto.MarshalTextString(msg) 148 » cset[path] = content
129 } 149 }
130 150
131 // Install creates a testing Context and installs common test facilities into 151 // Install creates a testing Context and installs common test facilities into
132 // it, returning the Environment to which they're bound. 152 // it, returning the Environment to which they're bound.
133 func Install() (context.Context, *Environment) { 153 func Install() (context.Context, *Environment) {
134 e := Environment{ 154 e := Environment{
135 Config: make(map[string]memory.ConfigSet), 155 Config: make(map[string]memory.ConfigSet),
136 } 156 }
137 157
138 // Get our starting context. This installs, among other things, in-memor y 158 // Get our starting context. This installs, among other things, in-memor y
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 e.Clock = clock.Get(c).(testclock.TestClock) 196 e.Clock = clock.Get(c).(testclock.TestClock)
177 197
178 // Install GAE config service settings. 198 // Install GAE config service settings.
179 c = settings.Use(c, settings.New(&settings.MemoryStorage{})) 199 c = settings.Use(c, settings.New(&settings.MemoryStorage{}))
180 200
181 // Setup luci-config configuration. 201 // Setup luci-config configuration.
182 c = memory.Use(c, e.Config) 202 c = memory.Use(c, e.Config)
183 e.ConfigIface = luciConfig.Get(c) 203 e.ConfigIface = luciConfig.Get(c)
184 204
185 // luci-config: Projects. 205 // luci-config: Projects.
186 » addProjectConfig := func(proj luciConfig.ProjectName, localName string, access ...string) { 206 » projectName := info.Get(c).AppID()
187 » » configSet, configPath := config.ProjectConfigPath(c, proj) 207 » addProjectConfig := func(proj luciConfig.ProjectName, access ...string) {
188 208 » » e.ModProjectConfig(c, proj, func(pcfg *svcconfig.ProjectConfig) {
189 » » var cfg configProto.ProjectCfg 209 » » » for _, a := range access {
190 » » e.modTextProtobuf(configSet, configPath, &cfg, func() { 210 » » » » parts := strings.SplitN(a, ":", 2)
191 » » » cfg.Name = &localName 211 » » » » group, field := parts[0], &pcfg.ReaderAuthGroups
192 » » » cfg.Access = access 212 » » » » if len(parts) == 2 {
213 » » » » » switch parts[1] {
214 » » » » » case "R":
215 » » » » » » break
216 » » » » » case "W":
217 » » » » » » field = &pcfg.WriterAuthGroups
218 » » » » » default:
219 » » » » » » panic(a)
220 » » » » » }
221 » » » » }
222 » » » » *field = append(*field, group)
223 » » » }
193 }) 224 })
194 } 225 }
195 » addProjectConfig("proj-foo", "Foo Project", "group:all") 226 » addProjectConfig("proj-foo", "all:R", "all:W")
196 » addProjectConfig("proj-bar", "Bar Project", "group:all") 227 » addProjectConfig("proj-bar", "all:R", "auth:W")
197 » addProjectConfig("proj-baz", "Baz Project", "group:all") 228 » addProjectConfig("proj-exclusive", "auth:R", "auth:W")
198 » addProjectConfig("proj-qux", "Qux Project", "group:all") 229
199 » addProjectConfig("proj-exclusive", "Exclusive Project", "group:auth") 230 » // Add a project without a LogDog project config.
231 » e.addConfigEntry("projects/proj-unconfigured", "not-logdog.cfg", "junk")
232
233 » configSet, configName := config.ProjectConfigPath(c, "proj-malformed")
234 » e.addConfigEntry(configSet, configName, "!!! not a text protobuf !!!")
200 235
201 // luci-config: Coordinator Defaults 236 // luci-config: Coordinator Defaults
202 » e.ModServiceConfig(c, func(cfg *svcconfig.Coordinator) { 237 » e.ModServiceConfig(c, func(cfg *svcconfig.Config) {
203 » » *cfg = svcconfig.Coordinator{ 238 » » cfg.Transport = &svcconfig.Transport{
239 » » » Type: &svcconfig.Transport_Pubsub{
240 » » » » Pubsub: &svcconfig.Transport_PubSub{
241 » » » » » Project: projectName,
242 » » » » » Topic: "test-topic",
243 » » » » },
244 » » » },
245 » » }
246 » » cfg.Coordinator = &svcconfig.Coordinator{
204 AdminAuthGroup: "admin", 247 AdminAuthGroup: "admin",
205 ServiceAuthGroup: "services", 248 ServiceAuthGroup: "services",
249 PrefixExpiration: google.NewDuration(24 * time.Hour),
206 } 250 }
207 }) 251 })
208 252
209 // Setup Tumble. This also adds the two Tumble indexes to datastore. 253 // Setup Tumble. This also adds the two Tumble indexes to datastore.
210 e.Tumble.EnableDelayedMutations(c) 254 e.Tumble.EnableDelayedMutations(c)
211 255
212 tcfg := e.Tumble.GetConfig(c) 256 tcfg := e.Tumble.GetConfig(c)
213 tcfg.Namespaced = true 257 tcfg.Namespaced = true
214 e.Tumble.UpdateSettings(c, tcfg) 258 e.Tumble.UpdateSettings(c, tcfg)
215 259
216 // Install authentication state. 260 // Install authentication state.
217 c = auth.WithState(c, &e.AuthState) 261 c = auth.WithState(c, &e.AuthState)
218 262
219 // Setup authentication state. 263 // Setup authentication state.
220 » e.JoinGroup("all") 264 » e.LeaveAllGroups()
221 265
222 // Setup our default Coordinator services. 266 // Setup our default Coordinator services.
223 e.Services = Services{ 267 e.Services = Services{
224 IS: func() (storage.Storage, error) { 268 IS: func() (storage.Storage, error) {
225 return &e.IntermediateStorage, nil 269 return &e.IntermediateStorage, nil
226 }, 270 },
227 GS: func() (gs.Client, error) { 271 GS: func() (gs.Client, error) {
228 return &e.GSClient, nil 272 return &e.GSClient, nil
229 }, 273 },
230 AP: func() (coordinator.ArchivalPublisher, error) { 274 AP: func() (coordinator.ArchivalPublisher, error) {
231 return &e.ArchivalPublisher, nil 275 return &e.ArchivalPublisher, nil
232 }, 276 },
233 } 277 }
234 c = coordinator.WithServices(c, &e.Services) 278 c = coordinator.WithServices(c, &e.Services)
235 279
236 return c, &e 280 return c, &e
237 } 281 }
238 282
239 // WithProjectNamespace runs f in proj's namespace, bypassing authentication 283 // WithProjectNamespace runs f in proj's namespace, bypassing authentication
240 // checks. 284 // checks.
241 func WithProjectNamespace(c context.Context, proj luciConfig.ProjectName, f func (context.Context)) { 285 func WithProjectNamespace(c context.Context, proj luciConfig.ProjectName, f func (context.Context)) {
242 if err := coordinator.WithProjectNamespaceNoAuth(&c, proj); err != nil { 286 if err := coordinator.WithProjectNamespaceNoAuth(&c, proj); err != nil {
243 panic(err) 287 panic(err)
244 } 288 }
245 f(c) 289 f(c)
246 } 290 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698