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

Side by Side Diff: tokenserver/appengine/impl/serviceaccounts/rpc_mint_oauth_token_grant.go

Issue 2993763002: tokenserver: Extract rules check into a separate function. (Closed)
Patch Set: more nits Created 3 years, 4 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 2017 The LUCI Authors. All rights reserved. 1 // Copyright 2017 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 serviceaccounts 5 package serviceaccounts
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "time" 9 "time"
10 10
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 // Fetch service account rules. They are hot in memory most of the time. 96 // Fetch service account rules. They are hot in memory most of the time.
97 rules, err := r.Rules(c) 97 rules, err := r.Rules(c)
98 if err != nil { 98 if err != nil {
99 // Don't put error details in the message, it may be returned to 99 // Don't put error details in the message, it may be returned to
100 // unauthorized callers. 100 // unauthorized callers.
101 logging.WithError(err).Errorf(c, "Failed to load service account s rules") 101 logging.WithError(err).Errorf(c, "Failed to load service account s rules")
102 return nil, grpc.Errorf(codes.Internal, "failed to load service accounts rules") 102 return nil, grpc.Errorf(codes.Internal, "failed to load service accounts rules")
103 } 103 }
104 104
105 » // Grab the rule for this account. Don't leak information about presence or 105 » // Check that requested usage is allowed and grab the corresponding rule .
106 » // absence of the account to the caller, they may not be authorized to s ee the 106 » rule, err := rules.Check(c, &RulesQuery{
107 » // account at all. 107 » » ServiceAccount: req.ServiceAccount,
108 » rule := rules.Rule(req.ServiceAccount) 108 » » Proxy: callerID,
109 » if rule == nil { 109 » » EndUser: endUserID,
110 » » logging.Errorf(c, "No rule for service account %q in the config rev %s", req.ServiceAccount, rules.ConfigRevision()) 110 » })
111 » » return nil, grpc.Errorf(codes.PermissionDenied, "unknown service account or not enough permissions to use it") 111 » if err != nil {
112 » } 112 » » return nil, err // it is already gRPC error, and it's already lo gged
113 » logging.Infof(c, "Found the matching rule %q in the config rev %s", rule .Rule.Name, rules.ConfigRevision())
114
115 » // If the caller is in 'Proxies' list, we assume it's known to us and we trust
116 » // it enough to start returning more detailed error messages.
117 » switch known, err := rule.Proxies.IsMember(c, callerID); {
118 » case err != nil:
119 » » logging.WithError(err).Errorf(c, "Failed to check membership of caller %q", callerID)
120 » » return nil, grpc.Errorf(codes.Internal, "membership check failed ")
121 » case !known:
122 » » logging.Errorf(c, "Caller %q is not authorized to use account %q ", callerID, req.ServiceAccount)
123 » » return nil, grpc.Errorf(codes.PermissionDenied, "unknown service account or not enough permissions to use it")
124 } 113 }
125 114
126 » // Check ValidityDuration next, it is easiest check. 115 » // ValidityDuration check is specific to this RPC, it's not done by 'Che ck'.
127 if req.ValidityDuration == 0 { 116 if req.ValidityDuration == 0 {
128 req.ValidityDuration = 3600 117 req.ValidityDuration = 3600
129 } 118 }
130 if req.ValidityDuration > rule.Rule.MaxGrantValidityDuration { 119 if req.ValidityDuration > rule.Rule.MaxGrantValidityDuration {
131 logging.Errorf(c, "Requested validity is larger than max allowed : %d > %d", req.ValidityDuration, rule.Rule.MaxGrantValidityDuration) 120 logging.Errorf(c, "Requested validity is larger than max allowed : %d > %d", req.ValidityDuration, rule.Rule.MaxGrantValidityDuration)
132 return nil, grpc.Errorf(codes.InvalidArgument, "per rule %q the validity duration should be <= %d", rule.Rule.Name, rule.Rule.MaxGrantValidityDu ration) 121 return nil, grpc.Errorf(codes.InvalidArgument, "per rule %q the validity duration should be <= %d", rule.Rule.Name, rule.Rule.MaxGrantValidityDu ration)
133 } 122 }
134 123
135 // Next is EndUsers check (involves membership lookups).
136 switch known, err := rule.EndUsers.IsMember(c, endUserID); {
137 case err != nil:
138 logging.WithError(err).Errorf(c, "Failed to check membership of end user %q", endUserID)
139 return nil, grpc.Errorf(codes.Internal, "membership check failed ")
140 case !known:
141 logging.Errorf(c, "End user %q is not authorized to use account %q", endUserID, req.ServiceAccount)
142 return nil, grpc.Errorf(
143 codes.PermissionDenied, "per rule %q the user %q is not authorized to use the service account %q",
144 rule.Rule.Name, endUserID, req.ServiceAccount)
145 }
146
147 // All checks are done! Note that AllowedScopes is checked later during 124 // All checks are done! Note that AllowedScopes is checked later during
148 // MintOAuthTokenViaGrant. Here we don't even know what OAuth scopes wil l be 125 // MintOAuthTokenViaGrant. Here we don't even know what OAuth scopes wil l be
149 // requested. 126 // requested.
150 var resp *minter.MintOAuthTokenGrantResponse 127 var resp *minter.MintOAuthTokenGrantResponse
151 p := mintParams{ 128 p := mintParams{
152 serviceAccount: req.ServiceAccount, 129 serviceAccount: req.ServiceAccount,
153 proxyID: callerID, 130 proxyID: callerID,
154 endUserID: endUserID, 131 endUserID: endUserID,
155 validityDuration: req.ValidityDuration, 132 validityDuration: req.ValidityDuration,
156 serviceVer: serviceVer, 133 serviceVer: serviceVer,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 logging.WithError(err).Errorf(c, "Error when signing the token") 178 logging.WithError(err).Errorf(c, "Error when signing the token")
202 return nil, grpc.Errorf(codes.Internal, "error when signing the token - %s", err) 179 return nil, grpc.Errorf(codes.Internal, "error when signing the token - %s", err)
203 } 180 }
204 181
205 return &minter.MintOAuthTokenGrantResponse{ 182 return &minter.MintOAuthTokenGrantResponse{
206 GrantToken: signed, 183 GrantToken: signed,
207 Expiry: google.NewTimestamp(expiry), 184 Expiry: google.NewTimestamp(expiry),
208 ServiceVersion: p.serviceVer, 185 ServiceVersion: p.serviceVer,
209 }, nil 186 }, nil
210 } 187 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698