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

Side by Side Diff: appengine/auth_service/config.py

Issue 2224163003: auth: Fix delegation.cfg config validation. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: Created 4 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
« no previous file with comments | « no previous file | appengine/auth_service/config_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2015 The LUCI Authors. All rights reserved. 1 # Copyright 2015 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 """Adapter between config service client and the rest of auth_service. 5 """Adapter between config service client and the rest of auth_service.
6 6
7 Basically a cron job that each minute refetches config files from config service 7 Basically a cron job that each minute refetches config files from config service
8 and modifies auth service datastore state if anything changed. 8 and modifies auth service datastore state if anything changed.
9 9
10 Following files are fetched: 10 Following files are fetched:
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 # update generates single AuthDB replication task instead of a bunch of them. 136 # update generates single AuthDB replication task instead of a bunch of them.
137 if dirty_in_authdb: 137 if dirty_in_authdb:
138 _update_authdb_configs(dirty_in_authdb) 138 _update_authdb_configs(dirty_in_authdb)
139 139
140 140
141 ### Integration with config validation framework. 141 ### Integration with config validation framework.
142 142
143 143
144 @validation.self_rule('delegation.cfg', config_pb2.DelegationConfig) 144 @validation.self_rule('delegation.cfg', config_pb2.DelegationConfig)
145 def validate_delegation_config(conf, ctx): 145 def validate_delegation_config(conf, ctx):
146 # Helper to valid a required list of identifies (or '*'). 146 def validate_service_list(name, lst):
147 def validate_ident_list(name, lst):
148 if not lst: 147 if not lst:
149 ctx.error('missing %s field', name) 148 ctx.error('missing %s field', name)
150 return 149 return
151 for uid in lst: 150 for uid in lst:
152 if uid != '*': 151 if uid == '*':
153 try: 152 continue
154 model.Identity.from_bytes(uid) 153 try:
155 except ValueError as exc: 154 ident = model.Identity.from_bytes(uid)
156 ctx.error('bad identity string "%s" in %s: %s', uid, name, exc) 155 if ident.kind != 'service':
156 ctx.error('%s: expecting "service:" identity, got "%s"', name, uid)
157 except ValueError as exc:
158 ctx.error('%s: bad identity string "%s": %s', name, uid, exc)
157 if '*' in lst and len(lst) != 1: 159 if '*' in lst and len(lst) != 1:
158 ctx.warning('redundant entries in %s, it has "*"" already', name) 160 ctx.warning('redundant entries in %s, it has "*"" already', name)
159 161
162 def validate_principal_list(name, lst, required=False):
163 if required and not lst:
164 ctx.error('missing %s field', name)
165 return
166 for p in lst:
167 if p == '*':
168 continue
169 if p.startswith('group:'):
170 group = p[len('group:'):]
171 if not model.is_valid_group_name(group):
172 ctx.error('%s: not a valid group name: %s', name, group)
173 continue
174 if '*' in p:
175 try:
176 model.IdentityGlob.from_bytes(p)
177 except ValueError as exc:
178 ctx.error('%s: not a valid identity glob "%s": %s', name, p, exc)
179 continue
180 try:
181 model.Identity.from_bytes(p)
182 except ValueError as exc:
183 ctx.error('%s: not a valid identity "%s": %s', name, p, exc)
184
160 for idx, r in enumerate(conf.rules): 185 for idx, r in enumerate(conf.rules):
161 with ctx.prefix('rules #%d: ', idx): 186 with ctx.prefix('rules #%d: ', idx):
162 validate_ident_list('user_id', r.user_id) 187 validate_service_list('target_service', r.target_service)
163 validate_ident_list('target_service', r.target_service) 188 validate_principal_list('user_id', r.user_id, required=True)
189 validate_principal_list(
190 'allowed_to_impersonate', r.allowed_to_impersonate)
164 if r.max_validity_duration <= 0: 191 if r.max_validity_duration <= 0:
165 ctx.error('max_validity_duration must be a positive integer') 192 ctx.error('max_validity_duration must be a positive integer')
166 for s in r.allowed_to_impersonate:
167 if s.startswith('group:'):
168 name = s[len('group:'):]
169 if not model.is_valid_group_name(name):
170 ctx.error('not a valid group name: %s', name)
171 continue
172 if '*' in s:
173 try:
174 model.IdentityGlob.from_bytes(s)
175 except ValueError as exc:
176 ctx.error('not a valid identity glob "%s": %s', s, exc)
177 continue
178 try:
179 model.Identity.from_bytes(s)
180 except ValueError as exc:
181 ctx.error('not a valid identity "%s": %s', s, exc)
182 193
183 194
184 # TODO(vadimsh): Below use validation context for real (e.g. emit multiple 195 # TODO(vadimsh): Below use validation context for real (e.g. emit multiple
185 # errors at once instead of aborting on the first one). 196 # errors at once instead of aborting on the first one).
186 197
187 198
188 @validation.self_rule('imports.cfg') 199 @validation.self_rule('imports.cfg')
189 def validate_imports_config(conf, ctx): 200 def validate_imports_config(conf, ctx):
190 try: 201 try:
191 importer.validate_config(conf) 202 importer.validate_config(conf)
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 try: 564 try:
554 location = gitiles.Location.parse(configs_url) 565 location = gitiles.Location.parse(configs_url)
555 return str(gitiles.Location( 566 return str(gitiles.Location(
556 hostname=location.hostname, 567 hostname=location.hostname,
557 project=location.project, 568 project=location.project,
558 treeish=rev, 569 treeish=rev,
559 path=posixpath.join(location.path, path))) 570 path=posixpath.join(location.path, path)))
560 except ValueError: 571 except ValueError:
561 # Not a gitiles URL, return as is. 572 # Not a gitiles URL, return as is.
562 return configs_url 573 return configs_url
OLDNEW
« no previous file with comments | « no previous file | appengine/auth_service/config_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698