| Index: appengine/logdog/coordinator/context.go
|
| diff --git a/appengine/logdog/coordinator/context.go b/appengine/logdog/coordinator/context.go
|
| index 6ca78c5af37332f33b7ed1c436cfaefc12da72d3..2d87cff0e4c82f1239726672b085c6c36c879d12 100644
|
| --- a/appengine/logdog/coordinator/context.go
|
| +++ b/appengine/logdog/coordinator/context.go
|
| @@ -13,6 +13,26 @@ import (
|
| "golang.org/x/net/context"
|
| )
|
|
|
| +// NamespaceAccessType specifies the type of namespace access that is being
|
| +// requested for WithProjectNamespace.
|
| +type NamespaceAccessType int
|
| +
|
| +const (
|
| + // NamespaceAccessNoAuth grants unconditional access to a project's namespace.
|
| + //
|
| + // This must only be used by endpoints that enforce admin- or service-only
|
| + // access.
|
| + NamespaceAccessNoAuth NamespaceAccessType = iota
|
| +
|
| + // NamespaceAccessREAD enforces READ permission access to a project's
|
| + // namespace.
|
| + NamespaceAccessREAD
|
| +
|
| + // NamespaceAccessWRITE enforces WRITE permission access to a project's
|
| + // namespace.
|
| + NamespaceAccessWRITE
|
| +)
|
| +
|
| type servicesKeyType int
|
|
|
| // WithServices installs the supplied Services instance into a Context.
|
| @@ -38,20 +58,7 @@ func GetServices(c context.Context) Services {
|
| //
|
| // If the current user does not have READ permission for the project, a
|
| // MembershipError will be returned.
|
| -func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName) error {
|
| - return withProjectNamespaceImpl(c, project, true)
|
| -}
|
| -
|
| -// WithProjectNamespaceNoAuth sets the current namespace to the project name. It
|
| -// does NOT assert that the current user has project access. This should only be
|
| -// used for service functions that are not acting on behalf of a user.
|
| -//
|
| -// It will fail if the project name is invalid.
|
| -func WithProjectNamespaceNoAuth(c *context.Context, project luciConfig.ProjectName) error {
|
| - return withProjectNamespaceImpl(c, project, false)
|
| -}
|
| -
|
| -func withProjectNamespaceImpl(c *context.Context, project luciConfig.ProjectName, auth bool) error {
|
| +func WithProjectNamespace(c *context.Context, project luciConfig.ProjectName, at NamespaceAccessType) error {
|
| // TODO(dnj): REQUIRE this to be non-empty once namespacing is mandatory.
|
| if project == "" {
|
| return nil
|
| @@ -62,12 +69,25 @@ func withProjectNamespaceImpl(c *context.Context, project luciConfig.ProjectName
|
| return err
|
| }
|
|
|
| - // Validate the user's READ access to the named project, if authenticating.
|
| - if auth {
|
| + // Validate the current user has the requested access.
|
| + switch at {
|
| + case NamespaceAccessNoAuth:
|
| + break
|
| +
|
| + case NamespaceAccessREAD:
|
| if err := IsProjectReader(*c, project); err != nil {
|
| - log.WithError(err).Errorf(*c, "User cannot access requested project.")
|
| + log.WithError(err).Errorf(*c, "User denied READ access to requested project.")
|
| + return err
|
| + }
|
| +
|
| + case NamespaceAccessWRITE:
|
| + if err := IsProjectWriter(*c, project); err != nil {
|
| + log.WithError(err).Errorf(*c, "User denied WRITE access to requested project.")
|
| return err
|
| }
|
| +
|
| + default:
|
| + return fmt.Errorf("unknown access type: %v", at)
|
| }
|
|
|
| pns := ProjectNamespace(project)
|
|
|