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

Side by Side Diff: appengine/logdog/coordinator/project.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 coordinator 5 package coordinator
6 6
7 import ( 7 import (
8 "strings" 8 "strings"
9 9
10 "github.com/luci/gae/service/datastore/meta"
11 "github.com/luci/gae/service/info" 10 "github.com/luci/gae/service/info"
12 » "github.com/luci/luci-go/common/config" 11 » "github.com/luci/luci-go/appengine/logdog/coordinator/config"
12 » luciConfig "github.com/luci/luci-go/common/config"
13 » log "github.com/luci/luci-go/common/logging"
13 "github.com/luci/luci-go/common/proto/logdog/svcconfig" 14 "github.com/luci/luci-go/common/proto/logdog/svcconfig"
14 "golang.org/x/net/context" 15 "golang.org/x/net/context"
15 ) 16 )
16 17
17 // projectNamespacePrefix is the datastore namespace prefix for project 18 const (
18 // namespaces. 19 » // projectNamespacePrefix is the datastore namespace prefix for project
19 const projectNamespacePrefix = "luci." 20 » // namespaces.
21 » projectNamespacePrefix = "luci."
22
23 » // projectConfigWorkers is the number of workers that will pull project
24 » // configs from the config service.
25 » projectConfigWorkers = 16
26 )
20 27
21 // ProjectNamespace returns the AppEngine namespace for a given luci-config 28 // ProjectNamespace returns the AppEngine namespace for a given luci-config
22 // project name. 29 // project name.
23 func ProjectNamespace(project config.ProjectName) string { 30 func ProjectNamespace(project luciConfig.ProjectName) string {
24 return projectNamespacePrefix + string(project) 31 return projectNamespacePrefix + string(project)
25 } 32 }
26 33
27 // ProjectFromNamespace returns the current project installed in the supplied 34 // ProjectFromNamespace returns the current project installed in the supplied
28 // Context's namespace. 35 // Context's namespace.
29 // 36 //
30 // If the namespace does not have a project namespace prefix, this function 37 // If the namespace does not have a project namespace prefix, this function
31 // will return an empty string. 38 // will return an empty string.
32 func ProjectFromNamespace(ns string) config.ProjectName { 39 func ProjectFromNamespace(ns string) luciConfig.ProjectName {
33 if !strings.HasPrefix(ns, projectNamespacePrefix) { 40 if !strings.HasPrefix(ns, projectNamespacePrefix) {
34 return "" 41 return ""
35 } 42 }
36 » return config.ProjectName(ns[len(projectNamespacePrefix):]) 43 » return luciConfig.ProjectName(ns[len(projectNamespacePrefix):])
37 } 44 }
38 45
39 // CurrentProject returns the current project based on the currently-loaded 46 // CurrentProject returns the current project based on the currently-loaded
40 // namespace. 47 // namespace.
41 // 48 //
42 // If there is no current namespace, or if the current namespace is not a valid 49 // If there is no current namespace, or if the current namespace is not a valid
43 // project namespace, an empty string will be returned. 50 // project namespace, an empty string will be returned.
44 func CurrentProject(c context.Context) config.ProjectName { 51 func CurrentProject(c context.Context) luciConfig.ProjectName {
45 if ns, ok := info.Get(c).GetNamespace(); ok { 52 if ns, ok := info.Get(c).GetNamespace(); ok {
46 return ProjectFromNamespace(ns) 53 return ProjectFromNamespace(ns)
47 } 54 }
48 return "" 55 return ""
49 } 56 }
50 57
51 // CurrentProjectConfig returns the project-specific configuration for the 58 // CurrentProjectConfig returns the project-specific configuration for the
52 // current project. 59 // current project.
53 // 60 //
54 // If there is no current project namespace, or if the current project has no 61 // If there is no current project namespace, or if the current project has no
55 // configuration, config.ErrInvalidConfig will be returned. 62 // configuration, config.ErrInvalidConfig will be returned.
56 func CurrentProjectConfig(c context.Context) (*svcconfig.ProjectConfig, error) { 63 func CurrentProjectConfig(c context.Context) (*svcconfig.ProjectConfig, error) {
57 return GetServices(c).ProjectConfig(c, CurrentProject(c)) 64 return GetServices(c).ProjectConfig(c, CurrentProject(c))
58 } 65 }
59 66
60 // AllProjectsWithNamespaces scans current namespaces and returns those that 67 // ActiveUserProjects returns a full list of all config service projects with
61 // belong to LUCI projects. 68 // a LogDog project configurations that the current user has READ access to.
nodir 2016/05/19 17:17:21 s/a //
dnj (Google) 2016/05/19 20:10:46 Done.
62 func AllProjectsWithNamespaces(c context.Context) ([]config.ProjectName, error) { 69 func ActiveUserProjects(c context.Context) (map[luciConfig.ProjectName]*svcconfi g.ProjectConfig, error) {
63 » var projects []config.ProjectName 70 » allPcfgs, err := config.AllProjectConfigs(c)
nodir 2016/05/19 17:17:21 I'd strongly recommend calling this function in a
dnj (Google) 2016/05/19 20:10:46 Agreed, and I'll put a TODO in, but this is not a
64 » err := meta.NamespacesWithPrefix(c, projectNamespacePrefix, func(ns stri ng) error {
65 » » if proj := ProjectFromNamespace(ns); proj != "" {
66 » » » projects = append(projects, proj)
67 » » }
68 » » return nil
69 » })
70 if err != nil { 71 if err != nil {
71 return nil, err 72 return nil, err
72 } 73 }
73 » return projects, nil 74
75 » for project, pcfg := range allPcfgs {
nodir 2016/05/19 17:17:21 add a TODO to make acl check concurrent. Auth grou
dnj (Google) 2016/05/19 20:10:46 If this is actually a problem, I think we need to
76 » » // Verify user access. This includes loading the project's confi g.
nodir 2016/05/19 17:17:21 it does not include that
dnj (Google) 2016/05/19 20:10:46 Done.
77 » » if err := IsProjectReader(c, pcfg); err != nil {
78 » » » delete(allPcfgs, project)
nodir 2016/05/19 17:17:21 this makes me nervous. I'd rather create a separat
dnj (Google) 2016/05/19 20:10:46 Agree about parallel construction. I thought abou
79
80 » » » // If it is a membership error, prune this project and c ontinue.
81 » » » // Otherwise, forward the error.
82 » » » if !IsMembershipError(err) {
83 » » » » // No configuration for this project, the config uration is invalid, or
84 » » » » // the user didn't have access. Remove it from t he list.
85 » » » » log.Fields{
86 » » » » » log.ErrorKey: err,
87 » » » » » "project": project,
88 » » » » }.Errorf(c, "Failed to check project.")
89 » » » » return nil, err
90 » » » }
91 » » }
92 » }
93 » return allPcfgs, nil
74 } 94 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698