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

Side by Side Diff: chrome/tools/build/generate_policy_source.py

Issue 108513011: Move chrome/app/policy into components/policy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years 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 | Annotate | Revision Log
« no previous file with comments | « chrome/tools/build/OWNERS ('k') | chrome/tools/build/win/make_policy_zip.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 '''python %prog [options] platform chromium_os_flag template
7
8 platform specifies which platform source is being generated for
9 and can be one of (win, mac, linux)
10 chromium_os_flag should be 1 if this is a Chromium OS build
11 template is the path to a .json policy template file.'''
12
13 from __future__ import with_statement
14 import json
15 from optparse import OptionParser
16 import re
17 import sys
18 import textwrap
19
20
21 CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome'
22 CHROMIUM_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Chromium'
23
24
25 class PolicyDetails:
26 """Parses a policy template and caches all its details."""
27
28 # Maps policy types to a tuple with 3 other types:
29 # - the equivalent base::Value::Type or 'TYPE_EXTERNAL' if the policy
30 # references external data
31 # - the equivalent Protobuf field type
32 # - the name of one of the protobufs for shared policy types
33 # TODO(joaodasilva): refactor the 'dict' type into a more generic 'json' type
34 # that can also be used to represent lists of other JSON objects.
35 TYPE_MAP = {
36 'dict': ('TYPE_DICTIONARY', 'string', 'String'),
37 'external': ('TYPE_EXTERNAL', 'string', 'String'),
38 'int': ('TYPE_INTEGER', 'int64', 'Integer'),
39 'int-enum': ('TYPE_INTEGER', 'int64', 'Integer'),
40 'list': ('TYPE_LIST', 'StringList', 'StringList'),
41 'main': ('TYPE_BOOLEAN', 'bool', 'Boolean'),
42 'string': ('TYPE_STRING', 'string', 'String'),
43 'string-enum': ('TYPE_STRING', 'string', 'String'),
44 }
45
46 class EnumItem:
47 def __init__(self, item):
48 self.caption = PolicyDetails._RemovePlaceholders(item['caption'])
49 self.value = item['value']
50
51 def __init__(self, policy, os, is_chromium_os):
52 self.id = policy['id']
53 self.name = policy['name']
54 self.is_deprecated = policy.get('deprecated', False)
55 self.is_device_only = policy.get('device_only', False)
56 self.schema = policy.get('schema', {})
57
58 expected_platform = 'chrome_os' if is_chromium_os else os.lower()
59 self.platforms = []
60 for platform, version in [ p.split(':') for p in policy['supported_on'] ]:
61 if not version.endswith('-'):
62 continue
63
64 if platform.startswith('chrome.'):
65 platform_sub = platform[7:]
66 if platform_sub == '*':
67 self.platforms.extend(['win', 'mac', 'linux'])
68 else:
69 self.platforms.append(platform_sub)
70 else:
71 self.platforms.append(platform)
72
73 self.platforms.sort()
74 self.is_supported = expected_platform in self.platforms
75
76 if not PolicyDetails.TYPE_MAP.has_key(policy['type']):
77 raise NotImplementedError('Unknown policy type for %s: %s' %
78 (policy['name'], policy['type']))
79 self.policy_type, self.protobuf_type, self.policy_protobuf_type = \
80 PolicyDetails.TYPE_MAP[policy['type']]
81 self.schema = policy['schema']
82
83 self.desc = '\n'.join(
84 map(str.strip,
85 PolicyDetails._RemovePlaceholders(policy['desc']).splitlines()))
86 self.caption = PolicyDetails._RemovePlaceholders(policy['caption'])
87 self.max_size = policy.get('max_size', 0)
88
89 items = policy.get('items')
90 if items is None:
91 self.items = None
92 else:
93 self.items = [ PolicyDetails.EnumItem(entry) for entry in items ]
94
95 PH_PATTERN = re.compile('<ph[^>]*>([^<]*|[^<]*<ex>([^<]*)</ex>[^<]*)</ph>')
96
97 # Simplistic grit placeholder stripper.
98 @staticmethod
99 def _RemovePlaceholders(text):
100 result = ''
101 pos = 0
102 for m in PolicyDetails.PH_PATTERN.finditer(text):
103 result += text[pos:m.start(0)]
104 result += m.group(2) or m.group(1)
105 pos = m.end(0)
106 result += text[pos:]
107 return result
108
109
110 def main():
111 parser = OptionParser(usage=__doc__)
112 parser.add_option('--pch', '--policy-constants-header', dest='header_path',
113 help='generate header file of policy constants',
114 metavar='FILE')
115 parser.add_option('--pcc', '--policy-constants-source', dest='source_path',
116 help='generate source file of policy constants',
117 metavar='FILE')
118 parser.add_option('--cpp', '--cloud-policy-protobuf',
119 dest='cloud_policy_proto_path',
120 help='generate cloud policy protobuf file',
121 metavar='FILE')
122 parser.add_option('--csp', '--chrome-settings-protobuf',
123 dest='chrome_settings_proto_path',
124 help='generate chrome settings protobuf file',
125 metavar='FILE')
126 parser.add_option('--cpd', '--cloud-policy-decoder',
127 dest='cloud_policy_decoder_path',
128 help='generate C++ code decoding the cloud policy protobuf',
129 metavar='FILE')
130
131 (opts, args) = parser.parse_args()
132
133 if len(args) != 3:
134 print 'exactly platform, chromium_os flag and input file must be specified.'
135 parser.print_help()
136 return 2
137
138 os = args[0]
139 is_chromium_os = args[1] == '1'
140 template_file_name = args[2]
141
142 template_file_contents = _LoadJSONFile(template_file_name)
143 policy_details = [ PolicyDetails(policy, os, is_chromium_os)
144 for policy in _Flatten(template_file_contents) ]
145 sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name)
146
147 def GenerateFile(path, writer, sorted=False):
148 if path:
149 with open(path, 'w') as f:
150 _OutputGeneratedWarningHeader(f, template_file_name)
151 writer(sorted and sorted_policy_details or policy_details, os, f)
152
153 GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True)
154 GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True)
155 GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf)
156 GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf)
157 GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder)
158
159 return 0
160
161
162 #------------------ shared helpers ---------------------------------#
163
164 def _OutputGeneratedWarningHeader(f, template_file_path):
165 f.write('//\n'
166 '// DO NOT MODIFY THIS FILE DIRECTLY!\n'
167 '// IT IS GENERATED BY generate_policy_source.py\n'
168 '// FROM ' + template_file_path + '\n'
169 '//\n\n')
170
171
172 COMMENT_WRAPPER = textwrap.TextWrapper()
173 COMMENT_WRAPPER.width = 80
174 COMMENT_WRAPPER.initial_indent = '// '
175 COMMENT_WRAPPER.subsequent_indent = '// '
176 COMMENT_WRAPPER.replace_whitespace = False
177
178
179 # Writes a comment, each line prefixed by // and wrapped to 80 spaces.
180 def _OutputComment(f, comment):
181 for line in comment.splitlines():
182 if len(line) == 0:
183 f.write('//')
184 else:
185 f.write(COMMENT_WRAPPER.fill(line))
186 f.write('\n')
187
188
189 # Returns an iterator over all the policies in |template_file_contents|.
190 def _Flatten(template_file_contents):
191 for policy in template_file_contents['policy_definitions']:
192 if policy['type'] == 'group':
193 for sub_policy in policy['policies']:
194 yield sub_policy
195 else:
196 yield policy
197
198
199 def _LoadJSONFile(json_file):
200 with open(json_file, 'r') as f:
201 text = f.read()
202 return eval(text)
203
204
205 #------------------ policy constants header ------------------------#
206
207 def _WritePolicyConstantHeader(policies, os, f):
208 f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n'
209 '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n'
210 '\n'
211 '#include <string>\n'
212 '\n'
213 '#include "base/basictypes.h"\n'
214 '#include "base/values.h"\n'
215 '#include "components/policy/core/common/policy_details.h"\n'
216 '\n'
217 'namespace policy {\n'
218 '\n'
219 'namespace internal {\n'
220 'struct SchemaData;\n'
221 '}\n\n')
222
223 if os == 'win':
224 f.write('// The windows registry path where Chrome policy '
225 'configuration resides.\n'
226 'extern const wchar_t kRegistryChromePolicyKey[];\n')
227
228 f.write('// Returns the PolicyDetails for |policy| if |policy| is a known\n'
229 '// Chrome policy, otherwise returns NULL.\n'
230 'const PolicyDetails* GetChromePolicyDetails('
231 'const std::string& policy);\n'
232 '\n'
233 '// Returns the schema data of the Chrome policy schema.\n'
234 'const internal::SchemaData* GetChromeSchemaData();\n'
235 '\n')
236 f.write('// Key names for the policy settings.\n'
237 'namespace key {\n\n')
238 for policy in policies:
239 # TODO(joaodasilva): Include only supported policies in
240 # configuration_policy_handler.cc and configuration_policy_handler_list.cc
241 # so that these names can be conditional on 'policy.is_supported'.
242 # http://crbug.com/223616
243 f.write('extern const char k' + policy.name + '[];\n')
244 f.write('\n} // namespace key\n\n'
245 '} // namespace policy\n\n'
246 '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n')
247
248
249 #------------------ policy constants source ------------------------#
250
251 # A mapping of the simple schema types to base::Value::Types.
252 SIMPLE_SCHEMA_NAME_MAP = {
253 'boolean': 'TYPE_BOOLEAN',
254 'integer': 'TYPE_INTEGER',
255 'null' : 'TYPE_NULL',
256 'number' : 'TYPE_DOUBLE',
257 'string' : 'TYPE_STRING',
258 }
259
260
261 class SchemaNodesGenerator:
262 """Builds the internal structs to represent a JSON schema."""
263
264 def __init__(self, shared_strings):
265 """Creates a new generator.
266
267 |shared_strings| is a map of strings to a C expression that evaluates to
268 that string at runtime. This mapping can be used to reuse existing string
269 constants."""
270 self.shared_strings = shared_strings
271 self.schema_nodes = []
272 self.property_nodes = []
273 self.properties_nodes = []
274 self.simple_types = {
275 'boolean': None,
276 'integer': None,
277 'null': None,
278 'number': None,
279 'string': None,
280 }
281 self.stringlist_type = None
282
283 def GetString(self, s):
284 return self.shared_strings[s] if s in self.shared_strings else '"%s"' % s
285
286 def AppendSchema(self, type, extra, comment=''):
287 index = len(self.schema_nodes)
288 self.schema_nodes.append((type, extra, comment))
289 return index
290
291 def GetSimpleType(self, name):
292 if self.simple_types[name] == None:
293 self.simple_types[name] = self.AppendSchema(
294 SIMPLE_SCHEMA_NAME_MAP[name],
295 -1,
296 'simple type: ' + name)
297 return self.simple_types[name]
298
299 def GetStringList(self):
300 if self.stringlist_type == None:
301 self.stringlist_type = self.AppendSchema(
302 'TYPE_LIST',
303 self.GetSimpleType('string'),
304 'simple type: stringlist')
305 return self.stringlist_type
306
307 def Generate(self, schema, name):
308 """Generates the structs for the given schema.
309
310 |schema|: a valid JSON schema in a dictionary.
311 |name|: the name of the current node, for the generated comments."""
312 # Simple types use shared nodes.
313 if schema['type'] in self.simple_types:
314 return self.GetSimpleType(schema['type'])
315
316 if schema['type'] == 'array':
317 # Special case for lists of strings, which is a common policy type.
318 if schema['items']['type'] == 'string':
319 return self.GetStringList()
320 return self.AppendSchema(
321 'TYPE_LIST',
322 self.Generate(schema['items'], 'items of ' + name))
323 elif schema['type'] == 'object':
324 # Reserve an index first, so that dictionaries come before their
325 # properties. This makes sure that the root node is the first in the
326 # SchemaNodes array.
327 index = self.AppendSchema('TYPE_DICTIONARY', -1)
328
329 if 'additionalProperties' in schema:
330 additionalProperties = self.Generate(
331 schema['additionalProperties'],
332 'additionalProperties of ' + name)
333 else:
334 additionalProperties = -1
335
336 # Properties must be sorted by name, for the binary search lookup.
337 # Note that |properties| must be evaluated immediately, so that all the
338 # recursive calls to Generate() append the necessary child nodes; if
339 # |properties| were a generator then this wouldn't work.
340 sorted_properties = sorted(schema.get('properties', {}).items())
341 properties = [ (self.GetString(key), self.Generate(schema, key))
342 for key, schema in sorted_properties ]
343 begin = len(self.property_nodes)
344 self.property_nodes += properties
345 end = len(self.property_nodes)
346 if index == 0:
347 self.root_properties_begin = begin
348 self.root_properties_end = end
349
350 extra = len(self.properties_nodes)
351 self.properties_nodes.append((begin, end, additionalProperties, name))
352
353 # Set the right data at |index| now.
354 self.schema_nodes[index] = ('TYPE_DICTIONARY', extra, name)
355 return index
356 else:
357 assert False
358
359 def Write(self, f):
360 """Writes the generated structs to the given file.
361
362 |f| an open file to write to."""
363 f.write('const internal::SchemaNode kSchemas[] = {\n'
364 '// Type Extra\n')
365 for type, extra, comment in self.schema_nodes:
366 type += ','
367 f.write(' { base::Value::%-18s %3d }, // %s\n' % (type, extra, comment))
368 f.write('};\n\n')
369
370 f.write('const internal::PropertyNode kPropertyNodes[] = {\n'
371 '// Property #Schema\n')
372 for key, schema in self.property_nodes:
373 key += ','
374 f.write(' { %-50s %7d },\n' % (key, schema))
375 f.write('};\n\n')
376
377 f.write('const internal::PropertiesNode kProperties[] = {\n'
378 '// Begin End Additional Properties\n')
379 for node in self.properties_nodes:
380 f.write(' { %5d, %5d, %5d }, // %s\n' % node)
381 f.write('};\n\n')
382
383 f.write('const internal::SchemaData kChromeSchemaData = {\n'
384 ' kSchemas,\n'
385 ' kPropertyNodes,\n'
386 ' kProperties,\n'
387 '};\n\n')
388
389
390 def _WritePolicyConstantSource(policies, os, f):
391 f.write('#include "policy/policy_constants.h"\n'
392 '\n'
393 '#include <algorithm>\n'
394 '\n'
395 '#include "base/logging.h"\n'
396 '#include "components/policy/core/common/schema_internal.h"\n'
397 '\n'
398 'namespace policy {\n'
399 '\n'
400 'namespace {\n'
401 '\n')
402
403 # Generate the Chrome schema.
404 chrome_schema = {
405 'type': 'object',
406 'properties': {},
407 }
408 shared_strings = {}
409 for policy in policies:
410 shared_strings[policy.name] = "key::k%s" % policy.name
411 if policy.is_supported:
412 chrome_schema['properties'][policy.name] = policy.schema
413
414 # Note: this list must be kept in sync with the known property list of the
415 # Chrome schema, so that binary seaching in the PropertyNode array gets the
416 # right index on this array as well. See the implementation of
417 # GetChromePolicyDetails() below.
418 f.write('const PolicyDetails kChromePolicyDetails[] = {\n'
419 '// is_deprecated is_device_policy id max_external_data_size\n')
420 for policy in policies:
421 if policy.is_supported:
422 f.write(' { %-14s %-16s %3s, %24s },\n' % (
423 'true,' if policy.is_deprecated else 'false,',
424 'true,' if policy.is_device_only else 'false,',
425 policy.id,
426 policy.max_size))
427 f.write('};\n\n')
428
429 schema_generator = SchemaNodesGenerator(shared_strings)
430 schema_generator.Generate(chrome_schema, 'root node')
431 schema_generator.Write(f)
432
433 f.write('bool CompareKeys(const internal::PropertyNode& node,\n'
434 ' const std::string& key) {\n'
435 ' return node.key < key;\n'
436 '}\n\n')
437
438 f.write('} // namespace\n\n')
439
440 if os == 'win':
441 f.write('#if defined(GOOGLE_CHROME_BUILD)\n'
442 'const wchar_t kRegistryChromePolicyKey[] = '
443 'L"' + CHROME_POLICY_KEY + '";\n'
444 '#else\n'
445 'const wchar_t kRegistryChromePolicyKey[] = '
446 'L"' + CHROMIUM_POLICY_KEY + '";\n'
447 '#endif\n\n')
448
449 f.write('const internal::SchemaData* GetChromeSchemaData() {\n'
450 ' return &kChromeSchemaData;\n'
451 '}\n\n')
452
453 f.write('const PolicyDetails* GetChromePolicyDetails('
454 'const std::string& policy) {\n'
455 ' // First index in kPropertyNodes of the Chrome policies.\n'
456 ' static const int begin_index = %s;\n'
457 ' // One-past-the-end of the Chrome policies in kPropertyNodes.\n'
458 ' static const int end_index = %s;\n' %
459 (schema_generator.root_properties_begin,
460 schema_generator.root_properties_end))
461 f.write(' const internal::PropertyNode* begin =\n'
462 ' kPropertyNodes + begin_index;\n'
463 ' const internal::PropertyNode* end = kPropertyNodes + end_index;\n'
464 ' const internal::PropertyNode* it =\n'
465 ' std::lower_bound(begin, end, policy, CompareKeys);\n'
466 ' if (it == end || it->key != policy)\n'
467 ' return NULL;\n'
468 ' // This relies on kPropertyNodes from begin_index to end_index\n'
469 ' // having exactly the same policies (and in the same order) as\n'
470 ' // kChromePolicyDetails, so that binary searching on the first\n'
471 ' // gets the same results as a binary search on the second would.\n'
472 ' // However, kPropertyNodes has the policy names and\n'
473 ' // kChromePolicyDetails doesn\'t, so we obtain the index into\n'
474 ' // the second array by searching the first to avoid duplicating\n'
475 ' // the policy name pointers.\n'
476 ' // Offsetting |it| from |begin| here obtains the index we\'re\n'
477 ' // looking for.\n'
478 ' size_t index = it - begin;\n'
479 ' CHECK_LT(index, arraysize(kChromePolicyDetails));\n'
480 ' return kChromePolicyDetails + index;\n'
481 '}\n\n')
482
483 f.write('namespace key {\n\n')
484 for policy in policies:
485 # TODO(joaodasilva): Include only supported policies in
486 # configuration_policy_handler.cc and configuration_policy_handler_list.cc
487 # so that these names can be conditional on 'policy.is_supported'.
488 # http://crbug.com/223616
489 f.write('const char k{name}[] = "{name}";\n'.format(name=policy.name))
490 f.write('\n} // namespace key\n\n'
491 '} // namespace policy\n')
492
493
494 #------------------ policy protobufs --------------------------------#
495
496 CHROME_SETTINGS_PROTO_HEAD = '''
497 syntax = "proto2";
498
499 option optimize_for = LITE_RUNTIME;
500
501 package enterprise_management;
502
503 // For StringList and PolicyOptions.
504 import "cloud_policy.proto";
505
506 '''
507
508
509 CLOUD_POLICY_PROTO_HEAD = '''
510 syntax = "proto2";
511
512 option optimize_for = LITE_RUNTIME;
513
514 package enterprise_management;
515
516 message StringList {
517 repeated string entries = 1;
518 }
519
520 message PolicyOptions {
521 enum PolicyMode {
522 // The given settings are applied regardless of user choice.
523 MANDATORY = 0;
524 // The user may choose to override the given settings.
525 RECOMMENDED = 1;
526 // No policy value is present and the policy should be ignored.
527 UNSET = 2;
528 }
529 optional PolicyMode mode = 1 [default = MANDATORY];
530 }
531
532 message BooleanPolicyProto {
533 optional PolicyOptions policy_options = 1;
534 optional bool value = 2;
535 }
536
537 message IntegerPolicyProto {
538 optional PolicyOptions policy_options = 1;
539 optional int64 value = 2;
540 }
541
542 message StringPolicyProto {
543 optional PolicyOptions policy_options = 1;
544 optional string value = 2;
545 }
546
547 message StringListPolicyProto {
548 optional PolicyOptions policy_options = 1;
549 optional StringList value = 2;
550 }
551
552 '''
553
554
555 # Field IDs [1..RESERVED_IDS] will not be used in the wrapping protobuf.
556 RESERVED_IDS = 2
557
558
559 def _WritePolicyProto(f, policy, fields):
560 _OutputComment(f, policy.caption + '\n\n' + policy.desc)
561 if policy.items is not None:
562 _OutputComment(f, '\nValid values:')
563 for item in policy.items:
564 _OutputComment(f, ' %s: %s' % (str(item.value), item.caption))
565 if policy.policy_type == 'TYPE_DICTIONARY':
566 _OutputComment(f, '\nValue schema:\n%s' %
567 json.dumps(policy.schema, sort_keys=True, indent=4,
568 separators=(',', ': ')))
569 _OutputComment(f, '\nSupported on: %s' % ', '.join(policy.platforms))
570 f.write('message %sProto {\n' % policy.name)
571 f.write(' optional PolicyOptions policy_options = 1;\n')
572 f.write(' optional %s %s = 2;\n' % (policy.protobuf_type, policy.name))
573 f.write('}\n\n')
574 fields += [ ' optional %sProto %s = %s;\n' %
575 (policy.name, policy.name, policy.id + RESERVED_IDS) ]
576
577
578 def _WriteChromeSettingsProtobuf(policies, os, f):
579 f.write(CHROME_SETTINGS_PROTO_HEAD)
580
581 fields = []
582 f.write('// PBs for individual settings.\n\n')
583 for policy in policies:
584 # Note: this protobuf also gets the unsupported policies, since it's an
585 # exaustive list of all the supported user policies on any platform.
586 if not policy.is_device_only:
587 _WritePolicyProto(f, policy, fields)
588
589 f.write('// --------------------------------------------------\n'
590 '// Big wrapper PB containing the above groups.\n\n'
591 'message ChromeSettingsProto {\n')
592 f.write(''.join(fields))
593 f.write('}\n\n')
594
595
596 def _WriteCloudPolicyProtobuf(policies, os, f):
597 f.write(CLOUD_POLICY_PROTO_HEAD)
598 f.write('message CloudPolicySettings {\n')
599 for policy in policies:
600 if policy.is_supported and not policy.is_device_only:
601 f.write(' optional %sPolicyProto %s = %s;\n' %
602 (policy.policy_protobuf_type, policy.name,
603 policy.id + RESERVED_IDS))
604 f.write('}\n\n')
605
606
607 #------------------ protobuf decoder -------------------------------#
608
609 CPP_HEAD = '''
610 #include <limits>
611 #include <string>
612
613 #include "base/basictypes.h"
614 #include "base/callback.h"
615 #include "base/json/json_reader.h"
616 #include "base/logging.h"
617 #include "base/memory/scoped_ptr.h"
618 #include "base/memory/weak_ptr.h"
619 #include "base/values.h"
620 #include "components/policy/core/common/cloud/cloud_external_data_manager.h"
621 #include "components/policy/core/common/external_data_fetcher.h"
622 #include "components/policy/core/common/policy_map.h"
623 #include "policy/policy_constants.h"
624 #include "policy/proto/cloud_policy.pb.h"
625
626 using google::protobuf::RepeatedPtrField;
627
628 namespace policy {
629
630 namespace em = enterprise_management;
631
632 base::Value* DecodeIntegerValue(google::protobuf::int64 value) {
633 if (value < std::numeric_limits<int>::min() ||
634 value > std::numeric_limits<int>::max()) {
635 LOG(WARNING) << "Integer value " << value
636 << " out of numeric limits, ignoring.";
637 return NULL;
638 }
639
640 return base::Value::CreateIntegerValue(static_cast<int>(value));
641 }
642
643 base::ListValue* DecodeStringList(const em::StringList& string_list) {
644 base::ListValue* list_value = new base::ListValue;
645 RepeatedPtrField<std::string>::const_iterator entry;
646 for (entry = string_list.entries().begin();
647 entry != string_list.entries().end(); ++entry) {
648 list_value->Append(base::Value::CreateStringValue(*entry));
649 }
650 return list_value;
651 }
652
653 base::Value* DecodeJson(const std::string& json) {
654 scoped_ptr<base::Value> root(
655 base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS));
656
657 if (!root)
658 LOG(WARNING) << "Invalid JSON string, ignoring: " << json;
659
660 // Accept any Value type that parsed as JSON, and leave it to the handler to
661 // convert and check the concrete type.
662 return root.release();
663 }
664
665 void DecodePolicy(const em::CloudPolicySettings& policy,
666 base::WeakPtr<CloudExternalDataManager> external_data_manager,
667 PolicyMap* map) {
668 '''
669
670
671 CPP_FOOT = '''}
672
673 } // namespace policy
674 '''
675
676
677 def _CreateValue(type, arg):
678 if type == 'TYPE_BOOLEAN':
679 return 'base::Value::CreateBooleanValue(%s)' % arg
680 elif type == 'TYPE_INTEGER':
681 return 'DecodeIntegerValue(%s)' % arg
682 elif type == 'TYPE_STRING':
683 return 'base::Value::CreateStringValue(%s)' % arg
684 elif type == 'TYPE_LIST':
685 return 'DecodeStringList(%s)' % arg
686 elif type == 'TYPE_DICTIONARY' or type == 'TYPE_EXTERNAL':
687 return 'DecodeJson(%s)' % arg
688 else:
689 raise NotImplementedError('Unknown type %s' % type)
690
691
692 def _CreateExternalDataFetcher(type, name):
693 if type == 'TYPE_EXTERNAL':
694 return 'new ExternalDataFetcher(external_data_manager, key::k%s)' % name
695 return 'NULL'
696
697
698 def _WritePolicyCode(f, policy):
699 membername = policy.name.lower()
700 proto_type = '%sPolicyProto' % policy.policy_protobuf_type
701 f.write(' if (policy.has_%s()) {\n' % membername)
702 f.write(' const em::%s& policy_proto = policy.%s();\n' %
703 (proto_type, membername))
704 f.write(' if (policy_proto.has_value()) {\n')
705 f.write(' PolicyLevel level = POLICY_LEVEL_MANDATORY;\n'
706 ' bool do_set = true;\n'
707 ' if (policy_proto.has_policy_options()) {\n'
708 ' do_set = false;\n'
709 ' switch(policy_proto.policy_options().mode()) {\n'
710 ' case em::PolicyOptions::MANDATORY:\n'
711 ' do_set = true;\n'
712 ' level = POLICY_LEVEL_MANDATORY;\n'
713 ' break;\n'
714 ' case em::PolicyOptions::RECOMMENDED:\n'
715 ' do_set = true;\n'
716 ' level = POLICY_LEVEL_RECOMMENDED;\n'
717 ' break;\n'
718 ' case em::PolicyOptions::UNSET:\n'
719 ' break;\n'
720 ' }\n'
721 ' }\n'
722 ' if (do_set) {\n')
723 f.write(' base::Value* value = %s;\n' %
724 (_CreateValue(policy.policy_type, 'policy_proto.value()')))
725 # TODO(bartfab): |value| == NULL indicates that the policy value could not be
726 # parsed successfully. Surface such errors in the UI.
727 f.write(' if (value) {\n')
728 f.write(' ExternalDataFetcher* external_data_fetcher = %s;\n' %
729 _CreateExternalDataFetcher(policy.policy_type, policy.name))
730 f.write(' map->Set(key::k%s, level, POLICY_SCOPE_USER,\n' %
731 policy.name)
732 f.write(' value, external_data_fetcher);\n'
733 ' }\n'
734 ' }\n'
735 ' }\n'
736 ' }\n')
737
738
739 def _WriteCloudPolicyDecoder(policies, os, f):
740 f.write(CPP_HEAD)
741 for policy in policies:
742 if policy.is_supported and not policy.is_device_only:
743 _WritePolicyCode(f, policy)
744 f.write(CPP_FOOT)
745
746
747 if __name__ == '__main__':
748 sys.exit(main())
OLDNEW
« no previous file with comments | « chrome/tools/build/OWNERS ('k') | chrome/tools/build/win/make_policy_zip.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698