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

Side by Side Diff: appengine/logdog/coordinator/auth.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 "errors"
9 "fmt" 8 "fmt"
9 "strings"
10 10
11 "github.com/luci/gae/service/info" 11 "github.com/luci/gae/service/info"
12 » "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 log "github.com/luci/luci-go/common/logging"
14 "github.com/luci/luci-go/common/proto/logdog/svcconfig"
15 "github.com/luci/luci-go/server/auth" 14 "github.com/luci/luci-go/server/auth"
16 "github.com/luci/luci-go/server/auth/identity" 15 "github.com/luci/luci-go/server/auth/identity"
17 "golang.org/x/net/context" 16 "golang.org/x/net/context"
18 ) 17 )
19 18
20 // ErrNoAccess is returned if the user has no access to the requested project.
21 var ErrNoAccess = config.ErrNoAccess
22
23 // IsAdminUser tests whether the current user belongs to the administrative 19 // IsAdminUser tests whether the current user belongs to the administrative
24 // users group. It will return an error if the user does not. 20 // users group.
21 //
22 // If the user is not a member of any groups, a MembershipError will be
nodir 2016/05/19 00:38:58 which "any groups" you are referring to in the con
dnj (Google) 2016/05/19 16:12:34 Done.
23 // returned.
25 func IsAdminUser(c context.Context) error { 24 func IsAdminUser(c context.Context) error {
26 » return isMember(c, func(cfg *svcconfig.Coordinator) string { 25 » cfg, err := GetServices(c).Config(c)
27 » » return cfg.AdminAuthGroup 26 » if err != nil {
28 » }) 27 » » return err
28 » }
29 » return checkMember(c, cfg.Coordinator.AdminAuthGroup)
29 } 30 }
30 31
31 // IsServiceUser tests whether the current user belongs to the backend services 32 // IsServiceUser tests whether the current user belongs to the backend services
32 // users group. It will return an error if the user does not. 33 // users group.
34 //
35 // If the user is not a member of any groups, a MembershipError will be
nodir 2016/05/19 00:38:58 same here
dnj (Google) 2016/05/19 16:12:34 Done.
36 // returned.
33 func IsServiceUser(c context.Context) error { 37 func IsServiceUser(c context.Context) error {
34 » return isMember(c, func(cfg *svcconfig.Coordinator) string { 38 » cfg, err := GetServices(c).Config(c)
35 » » return cfg.ServiceAuthGroup 39 » if err != nil {
36 » }) 40 » » return err
41 » }
42 » return checkMember(c, cfg.Coordinator.ServiceAuthGroup)
37 } 43 }
38 44
39 func isMember(c context.Context, groupNameFunc func(*svcconfig.Coordinator) stri ng) error { 45 // IsProjectReader tests whether the current user belongs to one of the
46 // project's declared reader groups.
47 //
48 // If the user is not a member of any groups, a MembershipError will be
nodir 2016/05/19 00:38:58 english: "any group"?
dnj (Google) 2016/05/19 16:12:34 Yeah this comment has gone through a few stages of
49 // returned.
50 func IsProjectReader(c context.Context, project luciConfig.ProjectName) error {
51 » pcfg, err := GetServices(c).ProjectConfig(c, project)
52 » if err != nil {
53 » » return err
54 » }
55 » return checkMember(c, pcfg.ReaderAuthGroups...)
56 }
57
58 func checkMember(c context.Context, groups ...string) error {
40 // On dev-appserver, the superuser has implicit group membership to 59 // On dev-appserver, the superuser has implicit group membership to
41 // everything. 60 // everything.
42 if info.Get(c).IsDevAppServer() { 61 if info.Get(c).IsDevAppServer() {
43 if u := auth.CurrentUser(c); u.Superuser { 62 if u := auth.CurrentUser(c); u.Superuser {
44 log.Fields{ 63 log.Fields{
45 "identity": u.Identity, 64 "identity": u.Identity,
65 "groups": groups,
46 }.Infof(c, "Granting superuser implicit group membership on development server.") 66 }.Infof(c, "Granting superuser implicit group membership on development server.")
47 return nil 67 return nil
48 } 68 }
49 } 69 }
50 70
51 » cfg, err := GetServices(c).Config(c) 71 » id := auth.CurrentIdentity(c)
52 » if err != nil { 72 » for _, group := range groups {
53 » » return err 73 » » is, err := auth.IsMember(c, group)
74 » » if err != nil {
75 » » » return err
76 » » }
77 » » if is {
78 » » » log.Fields{
79 » » » » "identity": id,
80 » » » » "group": group,
81 » » » }.Debugf(c, "User access granted.")
82 » » » return nil
83 » » }
54 } 84 }
55 85
56 » if cfg.Coordinator == nil { 86 » return &MembershipError{
57 » » return errors.New("no coordinator configuration") 87 » » Identity: id,
88 » » Groups: groups,
58 } 89 }
59
60 groupName := groupNameFunc(cfg.Coordinator)
61 if groupName == "" {
62 return errors.New("no auth group is configured")
63 }
64
65 is, err := auth.IsMember(c, groupName)
66 if err != nil {
67 return err
68 }
69 if !is {
70 return &MembershipError{
71 Identity: auth.CurrentIdentity(c),
72 Group: groupName,
73 }
74 }
75 return nil
76 } 90 }
77 91
78 // MembershipError is an error returned by group membership checking functions 92 // MembershipError is an error returned by group membership checking functions
79 // if the current identity is not a member of the requested group. 93 // if the current identity is not a member of the requested group.
80 type MembershipError struct { 94 type MembershipError struct {
81 Identity identity.Identity 95 Identity identity.Identity
82 » Group string 96 » Groups []string
83 } 97 }
84 98
85 func (e *MembershipError) Error() string { 99 func (e *MembershipError) Error() string {
86 » return fmt.Sprintf("user %q is not a member of group %q", e.Identity, e. Group) 100 » return fmt.Sprintf("user %q is not a member of [%s]", e.Identity, string s.Join(e.Groups, ", "))
87 } 101 }
88 102
89 // IsMembershipError returns whether a given error is a membership error. 103 // IsMembershipError returns whether a given error is a membership error.
90 func IsMembershipError(e error) bool { 104 func IsMembershipError(e error) bool {
91 _, ok := e.(*MembershipError) 105 _, ok := e.(*MembershipError)
92 return ok 106 return ok
93 } 107 }
OLDNEW
« no previous file with comments | « no previous file | appengine/logdog/coordinator/config/projects.go » ('j') | appengine/logdog/coordinator/context.go » ('J')

Powered by Google App Engine
This is Rietveld 408576698