Chromium Code Reviews| Index: appengine/logdog/coordinator/auth.go |
| diff --git a/appengine/logdog/coordinator/auth.go b/appengine/logdog/coordinator/auth.go |
| index 6c60d88ca59d415af90a354108c0e55131d3f090..6f85e80928ed24d3e9b23430b938e45206d207f3 100644 |
| --- a/appengine/logdog/coordinator/auth.go |
| +++ b/appengine/logdog/coordinator/auth.go |
| @@ -5,85 +5,99 @@ |
| package coordinator |
| import ( |
| - "errors" |
| "fmt" |
| + "strings" |
| "github.com/luci/gae/service/info" |
| - "github.com/luci/luci-go/appengine/logdog/coordinator/config" |
| + luciConfig "github.com/luci/luci-go/common/config" |
| log "github.com/luci/luci-go/common/logging" |
| - "github.com/luci/luci-go/common/proto/logdog/svcconfig" |
| "github.com/luci/luci-go/server/auth" |
| "github.com/luci/luci-go/server/auth/identity" |
| "golang.org/x/net/context" |
| ) |
| -// ErrNoAccess is returned if the user has no access to the requested project. |
| -var ErrNoAccess = config.ErrNoAccess |
| - |
| // IsAdminUser tests whether the current user belongs to the administrative |
| -// users group. It will return an error if the user does not. |
| +// users group. |
| +// |
| +// 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.
|
| +// returned. |
| func IsAdminUser(c context.Context) error { |
| - return isMember(c, func(cfg *svcconfig.Coordinator) string { |
| - return cfg.AdminAuthGroup |
| - }) |
| + cfg, err := GetServices(c).Config(c) |
| + if err != nil { |
| + return err |
| + } |
| + return checkMember(c, cfg.Coordinator.AdminAuthGroup) |
| } |
| // IsServiceUser tests whether the current user belongs to the backend services |
| -// users group. It will return an error if the user does not. |
| +// users group. |
| +// |
| +// 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.
|
| +// returned. |
| func IsServiceUser(c context.Context) error { |
| - return isMember(c, func(cfg *svcconfig.Coordinator) string { |
| - return cfg.ServiceAuthGroup |
| - }) |
| + cfg, err := GetServices(c).Config(c) |
| + if err != nil { |
| + return err |
| + } |
| + return checkMember(c, cfg.Coordinator.ServiceAuthGroup) |
| } |
| -func isMember(c context.Context, groupNameFunc func(*svcconfig.Coordinator) string) error { |
| +// IsProjectReader tests whether the current user belongs to one of the |
| +// project's declared reader groups. |
| +// |
| +// 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
|
| +// returned. |
| +func IsProjectReader(c context.Context, project luciConfig.ProjectName) error { |
| + pcfg, err := GetServices(c).ProjectConfig(c, project) |
| + if err != nil { |
| + return err |
| + } |
| + return checkMember(c, pcfg.ReaderAuthGroups...) |
| +} |
| + |
| +func checkMember(c context.Context, groups ...string) error { |
| // On dev-appserver, the superuser has implicit group membership to |
| // everything. |
| if info.Get(c).IsDevAppServer() { |
| if u := auth.CurrentUser(c); u.Superuser { |
| log.Fields{ |
| "identity": u.Identity, |
| + "groups": groups, |
| }.Infof(c, "Granting superuser implicit group membership on development server.") |
| return nil |
| } |
| } |
| - cfg, err := GetServices(c).Config(c) |
| - if err != nil { |
| - return err |
| - } |
| - |
| - if cfg.Coordinator == nil { |
| - return errors.New("no coordinator configuration") |
| - } |
| - |
| - groupName := groupNameFunc(cfg.Coordinator) |
| - if groupName == "" { |
| - return errors.New("no auth group is configured") |
| + id := auth.CurrentIdentity(c) |
| + for _, group := range groups { |
| + is, err := auth.IsMember(c, group) |
| + if err != nil { |
| + return err |
| + } |
| + if is { |
| + log.Fields{ |
| + "identity": id, |
| + "group": group, |
| + }.Debugf(c, "User access granted.") |
| + return nil |
| + } |
| } |
| - is, err := auth.IsMember(c, groupName) |
| - if err != nil { |
| - return err |
| - } |
| - if !is { |
| - return &MembershipError{ |
| - Identity: auth.CurrentIdentity(c), |
| - Group: groupName, |
| - } |
| + return &MembershipError{ |
| + Identity: id, |
| + Groups: groups, |
| } |
| - return nil |
| } |
| // MembershipError is an error returned by group membership checking functions |
| // if the current identity is not a member of the requested group. |
| type MembershipError struct { |
| Identity identity.Identity |
| - Group string |
| + Groups []string |
| } |
| func (e *MembershipError) Error() string { |
| - return fmt.Sprintf("user %q is not a member of group %q", e.Identity, e.Group) |
| + return fmt.Sprintf("user %q is not a member of [%s]", e.Identity, strings.Join(e.Groups, ", ")) |
| } |
| // IsMembershipError returns whether a given error is a membership error. |