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

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

Issue 1970823005: LogDog: Add prefix registration endpoint. (Closed) Base URL: https://github.com/luci/luci-go@logdog-project-archivist-useconfig
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 "fmt" 8 "fmt"
9 9
10 "github.com/luci/gae/service/info" 10 "github.com/luci/gae/service/info"
11 luciConfig "github.com/luci/luci-go/common/config" 11 luciConfig "github.com/luci/luci-go/common/config"
12 log "github.com/luci/luci-go/common/logging" 12 log "github.com/luci/luci-go/common/logging"
13 "golang.org/x/net/context" 13 "golang.org/x/net/context"
14 ) 14 )
15 15
16 // NamespaceAccessType specifies the type of namespace access that is being
17 // requested for WithProjectNamespace.
18 type NamespaceAccessType int
19
20 const (
21 // NamespaceAccessNoAuth grants unconditional access to a project's name space.
22 // This bypasses all ACL checks, and must only be used by service endpoi nts
23 // that explicitly apply ACLs elsewhere.
24 NamespaceAccessNoAuth NamespaceAccessType = iota
25
26 // NamespaceAccessREAD enforces READ permission access to a project's
27 // namespace.
28 NamespaceAccessREAD
29
30 // NamespaceAccessWRITE enforces WRITE permission access to a project's
31 // namespace.
32 NamespaceAccessWRITE
33 )
34
16 type servicesKeyType int 35 type servicesKeyType int
17 36
18 // WithServices installs the supplied Services instance into a Context. 37 // WithServices installs the supplied Services instance into a Context.
19 func WithServices(c context.Context, s Services) context.Context { 38 func WithServices(c context.Context, s Services) context.Context {
20 return context.WithValue(c, servicesKeyType(0), s) 39 return context.WithValue(c, servicesKeyType(0), s)
21 } 40 }
22 41
23 // GetServices gets the Services instance installed in the supplied Context. 42 // GetServices gets the Services instance installed in the supplied Context.
24 // 43 //
25 // If no Services has been installed, it will panic. 44 // If no Services has been installed, it will panic.
26 func GetServices(c context.Context) Services { 45 func GetServices(c context.Context) Services {
27 s, ok := c.Value(servicesKeyType(0)).(Services) 46 s, ok := c.Value(servicesKeyType(0)).(Services)
28 if !ok { 47 if !ok {
29 panic("no Services instance is installed") 48 panic("no Services instance is installed")
30 } 49 }
31 return s 50 return s
32 } 51 }
33 52
34 // WithProjectNamespace sets the current namespace to the project name. 53 // WithProjectNamespace sets the current namespace to the project name.
35 // 54 //
36 // It will return an error if the project name or the project's namespace is 55 // It will return an error if the project name or the project's namespace is
37 // invalid. 56 // invalid.
38 // 57 //
39 // If the current user does not have READ permission for the project, a 58 // If the current user does not have the requested permission for the project, a
40 // MembershipError will be returned. 59 // MembershipError will be returned.
41 func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName) er ror { 60 func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName, at NamespaceAccessType) error {
42 » return withProjectNamespaceImpl(c, project, true)
43 }
44
45 // WithProjectNamespaceNoAuth sets the current namespace to the project name. It
46 // does NOT assert that the current user has project access. This should only be
47 // used for service functions that are not acting on behalf of a user.
48 //
49 // It will fail if the project name is invalid.
50 func WithProjectNamespaceNoAuth(c *context.Context, project luciConfig.ProjectNa me) error {
51 » return withProjectNamespaceImpl(c, project, false)
52 }
53
54 func withProjectNamespaceImpl(c *context.Context, project luciConfig.ProjectName , auth bool) error {
55 ctx := *c 61 ctx := *c
56 62
57 // TODO(dnj): REQUIRE this to be non-empty once namespacing is mandatory . 63 // TODO(dnj): REQUIRE this to be non-empty once namespacing is mandatory .
58 if project == "" { 64 if project == "" {
59 return nil 65 return nil
60 } 66 }
61 67
62 if err := project.Validate(); err != nil { 68 if err := project.Validate(); err != nil {
63 log.WithError(err).Errorf(ctx, "Project name is invalid.") 69 log.WithError(err).Errorf(ctx, "Project name is invalid.")
64 return err 70 return err
65 } 71 }
66 72
67 » // Validate the user's READ access to the named project, if authenticati ng. 73 » // Validate the current user has the requested access.
68 » if auth { 74 » switch at {
75 » case NamespaceAccessNoAuth:
76 » » break
77
78 » case NamespaceAccessREAD:
69 pcfg, err := GetServices(ctx).ProjectConfig(ctx, project) 79 pcfg, err := GetServices(ctx).ProjectConfig(ctx, project)
70 if err != nil { 80 if err != nil {
71 log.WithError(err).Errorf(ctx, "Failed to load project c onfig.") 81 log.WithError(err).Errorf(ctx, "Failed to load project c onfig.")
72 return err 82 return err
73 } 83 }
74 84
75 » » if err := IsProjectReader(ctx, pcfg); err != nil { 85 » » if err := IsProjectReader(*c, pcfg); err != nil {
76 » » » log.WithError(err).Errorf(ctx, "User cannot access reque sted project.") 86 » » » log.WithError(err).Errorf(*c, "User denied READ access t o requested project.")
77 return err 87 return err
78 } 88 }
89
90 case NamespaceAccessWRITE:
91 pcfg, err := GetServices(ctx).ProjectConfig(ctx, project)
92 if err != nil {
93 log.WithError(err).Errorf(ctx, "Failed to load project c onfig.")
94 return err
95 }
96
97 if err := IsProjectWriter(*c, pcfg); err != nil {
98 log.WithError(err).Errorf(*c, "User denied WRITE access to requested project.")
99 return err
100 }
101
102 default:
103 return fmt.Errorf("unknown access type: %v", at)
79 } 104 }
80 105
81 pns := ProjectNamespace(project) 106 pns := ProjectNamespace(project)
82 nc, err := info.Get(ctx).Namespace(pns) 107 nc, err := info.Get(ctx).Namespace(pns)
83 if err != nil { 108 if err != nil {
84 log.Fields{ 109 log.Fields{
85 log.ErrorKey: err, 110 log.ErrorKey: err,
86 "project": project, 111 "project": project,
87 "namespace": pns, 112 "namespace": pns,
88 }.Errorf(ctx, "Failed to set namespace.") 113 }.Errorf(ctx, "Failed to set namespace.")
(...skipping 18 matching lines...) Expand all
107 if ns == "" { 132 if ns == "" {
108 return "" 133 return ""
109 } 134 }
110 135
111 project := ProjectFromNamespace(ns) 136 project := ProjectFromNamespace(ns)
112 if project != "" { 137 if project != "" {
113 return project 138 return project
114 } 139 }
115 panic(fmt.Errorf("current namespace %q does not begin with project names pace prefix (%q)", ns, projectNamespacePrefix)) 140 panic(fmt.Errorf("current namespace %q does not begin with project names pace prefix (%q)", ns, projectNamespacePrefix))
116 } 141 }
OLDNEW
« no previous file with comments | « appengine/logdog/coordinator/auth.go ('k') | appengine/logdog/coordinator/coordinatorTest/context.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698