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

Side by Side Diff: appengine/logdog/coordinator/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 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 "github.com/luci/luci-go/appengine/logdog/coordinator/config"
12 luciConfig "github.com/luci/luci-go/common/config" 11 luciConfig "github.com/luci/luci-go/common/config"
13 log "github.com/luci/luci-go/common/logging" 12 log "github.com/luci/luci-go/common/logging"
14 "golang.org/x/net/context" 13 "golang.org/x/net/context"
15 ) 14 )
16 15
17 type servicesKeyType int 16 type servicesKeyType int
18 17
19 // WithServices installs the supplied Services instance into a Context. 18 // WithServices installs the supplied Services instance into a Context.
20 func WithServices(c context.Context, s Services) context.Context { 19 func WithServices(c context.Context, s Services) context.Context {
21 return context.WithValue(c, servicesKeyType(0), s) 20 return context.WithValue(c, servicesKeyType(0), s)
22 } 21 }
23 22
24 // GetServices gets the Services instance installed in the supplied Context. 23 // GetServices gets the Services instance installed in the supplied Context.
25 // 24 //
26 // If no Services has been installed, it will panic. 25 // If no Services has been installed, it will panic.
27 func GetServices(c context.Context) Services { 26 func GetServices(c context.Context) Services {
28 s, ok := c.Value(servicesKeyType(0)).(Services) 27 s, ok := c.Value(servicesKeyType(0)).(Services)
29 if !ok { 28 if !ok {
30 panic("no Services instance is installed") 29 panic("no Services instance is installed")
31 } 30 }
32 return s 31 return s
33 } 32 }
34 33
35 // WithProjectNamespace sets the current namespace to the project name. 34 // WithProjectNamespace sets the current namespace to the project name.
36 // 35 //
37 // It will fail if either the project name or the project's namespace is 36 // It will return an error if the project name or the project's namespace is
38 // invalid. In the event of an error, the supplied Context will be not be 37 // invalid
nodir 2016/05/19 00:38:58 period missing
dnj (Google) 2016/05/19 16:12:34 Done.
39 // modified or invalidated. 38 //
39 // If the current user does not have READ permission for the project, a
40 // MembershipError will be returned.
40 func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName) er ror { 41 func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName) er ror {
41 return withProjectNamespaceImpl(c, project, true) 42 return withProjectNamespaceImpl(c, project, true)
42 } 43 }
43 44
44 // WithProjectNamespaceNoAuth sets the current namespace to the project name. It 45 // WithProjectNamespaceNoAuth sets the current namespace to the project name. It
45 // does NOT assert that the current user has project access. This should only be 46 // does NOT assert that the current user has project access. This should only be
46 // used for service functions that are not acting on behalf of a user. 47 // used for service functions that are not acting on behalf of a user.
47 // 48 //
48 // It will fail if the project name is invalid. 49 // It will fail if the project name is invalid.
49 func WithProjectNamespaceNoAuth(c *context.Context, project luciConfig.ProjectNa me) error { 50 func WithProjectNamespaceNoAuth(c *context.Context, project luciConfig.ProjectNa me) error {
50 return withProjectNamespaceImpl(c, project, false) 51 return withProjectNamespaceImpl(c, project, false)
51 } 52 }
52 53
53 func withProjectNamespaceImpl(c *context.Context, project luciConfig.ProjectName , auth bool) error { 54 func withProjectNamespaceImpl(c *context.Context, project luciConfig.ProjectName , auth bool) error {
54 // TODO(dnj): REQUIRE this to be non-empty once namespacing is mandatory . 55 // TODO(dnj): REQUIRE this to be non-empty once namespacing is mandatory .
55 if project == "" { 56 if project == "" {
56 log.Debugf(*c, "Using default namespace.")
57 return nil 57 return nil
58 } 58 }
59 59
60 if err := project.Validate(); err != nil { 60 if err := project.Validate(); err != nil {
61 » » log.Fields{ 61 » » log.WithError(err).Errorf(*c, "Project name is invalid.")
62 » » » log.ErrorKey: err,
63 » » » "project": project,
64 » » }.Errorf(*c, "Project name is invalid.")
65 return err 62 return err
66 } 63 }
67 64
68 » // Validate the user's access to the named project, if authenticating. 65 » // Validate the user's READ access to the named project, if authenticati ng.
69 if auth { 66 if auth {
70 » » if err := config.AssertProjectAccess(*c, project); err != nil { 67 » » if err := IsProjectReader(*c, project); err != nil {
71 » » » log.Fields{ 68 » » » log.WithError(err).Errorf(*c, "User cannot access reques ted project.")
72 » » » » log.ErrorKey: err,
73 » » » » "project": project,
74 » » » }.Errorf(*c, "User cannot access requested project.")
75 return err 69 return err
76 } 70 }
77 } 71 }
78 72
79 pns := ProjectNamespace(project) 73 pns := ProjectNamespace(project)
80 nc, err := info.Get(*c).Namespace(pns) 74 nc, err := info.Get(*c).Namespace(pns)
81 if err != nil { 75 if err != nil {
82 log.Fields{ 76 log.Fields{
83 log.ErrorKey: err, 77 log.ErrorKey: err,
84 "project": project, 78 "project": project,
85 "namespace": pns, 79 "namespace": pns,
86 }.Errorf(*c, "Failed to set namespace.") 80 }.Errorf(*c, "Failed to set namespace.")
87 return err 81 return err
88 } 82 }
89 83
90 log.Fields{
91 "project": project,
92 }.Debugf(*c, "Using project namespace.")
93 *c = nc 84 *c = nc
94 return nil 85 return nil
95 } 86 }
96 87
97 // Project returns the current project installed in the supplied Context's 88 // Project returns the current project installed in the supplied Context's
98 // namespace. 89 // namespace.
99 // 90 //
100 // This function is called with the expectation that the Context is in a 91 // This function is called with the expectation that the Context is in a
101 // namespace conforming to ProjectNamespace. If this is not the case, this 92 // namespace conforming to ProjectNamespace. If this is not the case, this
102 // method will panic. 93 // method will panic.
103 func Project(c context.Context) luciConfig.ProjectName { 94 func Project(c context.Context) luciConfig.ProjectName {
104 ns, _ := info.Get(c).GetNamespace() 95 ns, _ := info.Get(c).GetNamespace()
105 96
106 // TODO(dnj): Remove the empty namespace/project exception once we no lo nger 97 // TODO(dnj): Remove the empty namespace/project exception once we no lo nger
107 // support that. 98 // support that.
108 if ns == "" { 99 if ns == "" {
109 return "" 100 return ""
110 } 101 }
111 102
112 project := ProjectFromNamespace(ns) 103 project := ProjectFromNamespace(ns)
113 if project != "" { 104 if project != "" {
114 return project 105 return project
115 } 106 }
116 panic(fmt.Errorf("current namespace %q does not begin with project names pace prefix (%q)", ns, projectNamespacePrefix)) 107 panic(fmt.Errorf("current namespace %q does not begin with project names pace prefix (%q)", ns, projectNamespacePrefix))
117 } 108 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698