| OLD | NEW |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. | 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Package access implements a config service access check against a project | 5 // Package access implements a config service access check against a project |
| 6 // config client. | 6 // config client. |
| 7 // | 7 // |
| 8 // Note that this is a soft check, as the true access authority is the config | 8 // Note that this is a soft check, as the true access authority is the config |
| 9 // service, and this check is not hitting that service. | 9 // service, and this check is not hitting that service. |
| 10 // | 10 // |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 // Not a project config set, so neither remaining Authority can
access. | 45 // Not a project config set, so neither remaining Authority can
access. |
| 46 return ErrNoAccess | 46 return ErrNoAccess |
| 47 } | 47 } |
| 48 | 48 |
| 49 // Load the project config. We execute this RPC as the service, not the
user, | 49 // Load the project config. We execute this RPC as the service, not the
user, |
| 50 // so while this will recurse (and hopefully take advantage of the cache
), it | 50 // so while this will recurse (and hopefully take advantage of the cache
), it |
| 51 // will not trigger an infinite access check loop. | 51 // will not trigger an infinite access check loop. |
| 52 var pcfg configPB.ProjectCfg | 52 var pcfg configPB.ProjectCfg |
| 53 if err := cfgclient.Get(c, cfgclient.AsService, projectConfigSet, cfgcli
ent.ProjectConfigPath, | 53 if err := cfgclient.Get(c, cfgclient.AsService, projectConfigSet, cfgcli
ent.ProjectConfigPath, |
| 54 textproto.Message(&pcfg), nil); err != nil { | 54 textproto.Message(&pcfg), nil); err != nil { |
| 55 » » return errors.Annotate(err).Reason("failed to load %(path)q in %
(configSet)q"). | 55 » » return errors.Annotate(err, "failed to load %q in %q", |
| 56 » » » D("path", cfgclient.ProjectConfigPath).D("configSet", pr
ojectConfigSet).Err() | 56 » » » cfgclient.ProjectConfigPath, projectConfigSet).Err() |
| 57 } | 57 } |
| 58 | 58 |
| 59 id := identity.AnonymousIdentity | 59 id := identity.AnonymousIdentity |
| 60 if a == backend.AsUser { | 60 if a == backend.AsUser { |
| 61 id = auth.CurrentIdentity(c) | 61 id = auth.CurrentIdentity(c) |
| 62 } | 62 } |
| 63 checkGroups := make([]string, 0, len(pcfg.Access)) | 63 checkGroups := make([]string, 0, len(pcfg.Access)) |
| 64 for _, access := range pcfg.Access { | 64 for _, access := range pcfg.Access { |
| 65 if group, ok := trimPrefix(access, "group:"); ok { | 65 if group, ok := trimPrefix(access, "group:"); ok { |
| 66 // Check group membership. | 66 // Check group membership. |
| 67 checkGroups = append(checkGroups, group) | 67 checkGroups = append(checkGroups, group) |
| 68 } else { | 68 } else { |
| 69 // If there is no ":" in the access string, this is a us
er ACL. | 69 // If there is no ":" in the access string, this is a us
er ACL. |
| 70 if strings.IndexRune(access, ':') < 0 { | 70 if strings.IndexRune(access, ':') < 0 { |
| 71 access = "user:" + access | 71 access = "user:" + access |
| 72 } | 72 } |
| 73 if identity.Identity(access) == id { | 73 if identity.Identity(access) == id { |
| 74 return nil | 74 return nil |
| 75 } | 75 } |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 | 78 |
| 79 // No individual accesses, check groups. | 79 // No individual accesses, check groups. |
| 80 if len(checkGroups) > 0 { | 80 if len(checkGroups) > 0 { |
| 81 switch canAccess, err := auth.IsMember(c, checkGroups...); { | 81 switch canAccess, err := auth.IsMember(c, checkGroups...); { |
| 82 case err != nil: | 82 case err != nil: |
| 83 » » » return errors.Annotate(err).Reason("failed to check grou
p membership").Err() | 83 » » » return errors.Annotate(err, "failed to check group membe
rship").Err() |
| 84 case canAccess: | 84 case canAccess: |
| 85 return nil | 85 return nil |
| 86 } | 86 } |
| 87 } | 87 } |
| 88 return ErrNoAccess | 88 return ErrNoAccess |
| 89 } | 89 } |
| 90 | 90 |
| 91 func trimPrefix(v, pfx string) (string, bool) { | 91 func trimPrefix(v, pfx string) (string, bool) { |
| 92 if strings.HasPrefix(v, pfx) { | 92 if strings.HasPrefix(v, pfx) { |
| 93 return v[len(pfx):], true | 93 return v[len(pfx):], true |
| 94 } | 94 } |
| 95 return v, false | 95 return v, false |
| 96 } | 96 } |
| OLD | NEW |