15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)'''python %prog [options] platform chromium_os_flag template 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)platform specifies which platform source is being generated for 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) and can be one of (win, mac, linux) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)chromium_os_flag should be 1 if this is a Chromium OS build 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template is the path to a .json policy template file.''' 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from __future__ import with_statement 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochfrom functools import partial 15ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochimport json 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from optparse import OptionParser 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import re 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import textwrap 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochimport types 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome' 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CHROMIUM_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Chromium' 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class PolicyDetails: 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) """Parses a policy template and caches all its details.""" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # Maps policy types to a tuple with 3 other types: 313240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch # - the equivalent base::Value::Type or 'TYPE_EXTERNAL' if the policy 323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch # references external data 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # - the equivalent Protobuf field type 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # - the name of one of the protobufs for shared policy types 35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch # TODO(joaodasilva): refactor the 'dict' type into a more generic 'json' type 36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch # that can also be used to represent lists of other JSON objects. 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TYPE_MAP = { 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'dict': ('TYPE_DICTIONARY', 'string', 'String'), 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'external': ('TYPE_EXTERNAL', 'string', 'String'), 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'int': ('TYPE_INTEGER', 'int64', 'Integer'), 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'int-enum': ('TYPE_INTEGER', 'int64', 'Integer'), 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'list': ('TYPE_LIST', 'StringList', 'StringList'), 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'main': ('TYPE_BOOLEAN', 'bool', 'Boolean'), 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'string': ('TYPE_STRING', 'string', 'String'), 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'string-enum': ('TYPE_STRING', 'string', 'String'), 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 'string-enum-list': ('TYPE_LIST', 'StringList', 'StringList'), 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch class EnumItem: 502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch def __init__(self, item): 512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch self.caption = PolicyDetails._RemovePlaceholders(item['caption']) 522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch self.value = item['value'] 532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def __init__(self, policy, os, is_chromium_os): 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.id = policy['id'] 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.name = policy['name'] 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci features = policy.get('features', {}) 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.can_be_recommended = features.get('can_be_recommended', False) 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.can_be_mandatory = features.get('can_be_mandatory', True) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.is_deprecated = policy.get('deprecated', False) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.is_device_only = policy.get('device_only', False) 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.schema = policy.get('schema', {}) 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.has_enterprise_default = 'default_for_enterprise_users' in policy 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if self.has_enterprise_default: 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci self.enterprise_default = policy['default_for_enterprise_users'] 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) expected_platform = 'chrome_os' if is_chromium_os else os.lower() 68ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.platforms = [] 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for platform, version in [ p.split(':') for p in policy['supported_on'] ]: 70ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if not version.endswith('-'): 71ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch continue 72ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 73ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if platform.startswith('chrome.'): 74ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch platform_sub = platform[7:] 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if platform_sub == '*': 76ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.platforms.extend(['win', 'mac', 'linux']) 77ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else: 78ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.platforms.append(platform_sub) 79ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch else: 80ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.platforms.append(platform) 81ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.platforms.sort() 83ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.is_supported = expected_platform in self.platforms 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if not PolicyDetails.TYPE_MAP.has_key(policy['type']): 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) raise NotImplementedError('Unknown policy type for %s: %s' % 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (policy['name'], policy['type'])) 883240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch self.policy_type, self.protobuf_type, self.policy_protobuf_type = \ 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PolicyDetails.TYPE_MAP[policy['type']] 90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch self.schema = policy['schema'] 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) self.desc = '\n'.join( 932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch map(str.strip, 942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch PolicyDetails._RemovePlaceholders(policy['desc']).splitlines())) 952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch self.caption = PolicyDetails._RemovePlaceholders(policy['caption']) 963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch self.max_size = policy.get('max_size', 0) 972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch 982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch items = policy.get('items') 992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch if items is None: 1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch self.items = None 1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch else: 1022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch self.items = [ PolicyDetails.EnumItem(entry) for entry in items ] 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PH_PATTERN = re.compile('<ph[^>]*>([^<]*|[^<]*<ex>([^<]*)</ex>[^<]*)</ph>') 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # Simplistic grit placeholder stripper. 1072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch @staticmethod 1082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch def _RemovePlaceholders(text): 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result = '' 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pos = 0 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for m in PolicyDetails.PH_PATTERN.finditer(text): 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result += text[pos:m.start(0)] 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result += m.group(2) or m.group(1) 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pos = m.end(0) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result += text[pos:] 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def main(): 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser = OptionParser(usage=__doc__) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('--pch', '--policy-constants-header', dest='header_path', 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help='generate header file of policy constants', 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metavar='FILE') 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.add_option('--pcc', '--policy-constants-source', dest='source_path', 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help='generate source file of policy constants', 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metavar='FILE') 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option('--cpp', '--cloud-policy-protobuf', 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest='cloud_policy_proto_path', 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) help='generate cloud policy protobuf file', 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metavar='FILE') 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option('--csp', '--chrome-settings-protobuf', 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest='chrome_settings_proto_path', 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) help='generate chrome settings protobuf file', 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) metavar='FILE') 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) parser.add_option('--cpd', '--cloud-policy-decoder', 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dest='cloud_policy_decoder_path', 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) help='generate C++ code decoding the cloud policy protobuf', 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) metavar='FILE') 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (opts, args) = parser.parse_args() 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(args) != 3: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print 'exactly platform, chromium_os flag and input file must be specified.' 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parser.print_help() 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 2 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) os = args[0] 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) is_chromium_os = args[1] == '1' 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template_file_name = args[2] 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) template_file_contents = _LoadJSONFile(template_file_name) 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy_details = [ PolicyDetails(policy, os, is_chromium_os) 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in _Flatten(template_file_contents) ] 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name) 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) def GenerateFile(path, writer, sorted=False): 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if path: 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) with open(path, 'w') as f: 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _OutputGeneratedWarningHeader(f, template_file_name) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer(sorted and sorted_policy_details or policy_details, os, f) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True) 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#------------------ shared helpers ---------------------------------# 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _OutputGeneratedWarningHeader(f, template_file_path): 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('//\n' 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '// DO NOT MODIFY THIS FILE DIRECTLY!\n' 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '// IT IS GENERATED BY generate_policy_source.py\n' 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '// FROM ' + template_file_path + '\n' 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '//\n\n') 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMENT_WRAPPER = textwrap.TextWrapper() 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMENT_WRAPPER.width = 80 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMENT_WRAPPER.initial_indent = '// ' 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMENT_WRAPPER.subsequent_indent = '// ' 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMMENT_WRAPPER.replace_whitespace = False 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Writes a comment, each line prefixed by // and wrapped to 80 spaces. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _OutputComment(f, comment): 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for line in comment.splitlines(): 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if len(line) == 0: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f.write('//') 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f.write(COMMENT_WRAPPER.fill(line)) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) f.write('\n') 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Returns an iterator over all the policies in |template_file_contents|. 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def _Flatten(template_file_contents): 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for policy in template_file_contents['policy_definitions']: 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if policy['type'] == 'group': 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for sub_policy in policy['policies']: 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yield sub_policy 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else: 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) yield policy 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _LoadJSONFile(json_file): 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) with open(json_file, 'r') as f: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) text = f.read() 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return eval(text) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#------------------ policy constants header ------------------------# 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WritePolicyConstantHeader(policies, os, f): 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n' 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n' 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '\n' 220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#include <string>\n' 221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '\n' 2223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch '#include "base/basictypes.h"\n' 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#include "base/values.h"\n' 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '#include "components/policy/core/common/policy_details.h"\n' 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '#include "components/policy/core/common/policy_map.h"\n' 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '\n' 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'namespace policy {\n' 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n' 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'namespace internal {\n' 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'struct SchemaData;\n' 231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '}\n\n') 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if os == 'win': 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('// The windows registry path where Chrome policy ' 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'configuration resides.\n' 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'extern const wchar_t kRegistryChromePolicyKey[];\n') 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci f.write('#if defined (OS_CHROMEOS)\n' 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '// Sets default values for enterprise users.\n' 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'void SetEnterpriseUsersDefaults(PolicyMap* policy_map);\n' 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '#endif\n' 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '\n' 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '// Returns the PolicyDetails for |policy| if |policy| is a known\n' 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '// Chrome policy, otherwise returns NULL.\n' 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'const PolicyDetails* GetChromePolicyDetails(' 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'const std::string& policy);\n' 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '\n' 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '// Returns the schema data of the Chrome policy schema.\n' 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'const internal::SchemaData* GetChromeSchemaData();\n' 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n') 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('// Key names for the policy settings.\n' 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'namespace key {\n\n') 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # TODO(joaodasilva): Include only supported policies in 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # configuration_policy_handler.cc and configuration_policy_handler_list.cc 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # so that these names can be conditional on 'policy.is_supported'. 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # http://crbug.com/223616 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('extern const char k' + policy.name + '[];\n') 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('\n} // namespace key\n\n' 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '} // namespace policy\n\n' 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n') 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#------------------ policy constants source ------------------------# 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 266f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)# A mapping of the simple schema types to base::Value::Types. 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SIMPLE_SCHEMA_NAME_MAP = { 268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'boolean': 'TYPE_BOOLEAN', 269f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'integer': 'TYPE_INTEGER', 270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'null' : 'TYPE_NULL', 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'number' : 'TYPE_DOUBLE', 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'string' : 'TYPE_STRING', 273f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SchemaNodesGenerator: 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Builds the internal structs to represent a JSON schema.""" 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def __init__(self, shared_strings): 279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Creates a new generator. 280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) |shared_strings| is a map of strings to a C expression that evaluates to 282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) that string at runtime. This mapping can be used to reuse existing string 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) constants.""" 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.shared_strings = shared_strings 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.schema_nodes = [] 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.property_nodes = [] 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.properties_nodes = [] 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.restriction_nodes = [] 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.int_enums = [] 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.string_enums = [] 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.simple_types = { 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'boolean': None, 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'integer': None, 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'null': None, 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'number': None, 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'string': None, 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.stringlist_type = None 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.ranges = {} 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.id_map = {} 301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def GetString(self, s): 303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if s in self.shared_strings: 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.shared_strings[s] 305c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # Generate JSON escaped string, which is slightly different from desired 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # C/C++ escaped string. Known differences includes unicode escaping format. 307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return json.dumps(s) 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def AppendSchema(self, type, extra, comment=''): 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) index = len(self.schema_nodes) 311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.schema_nodes.append((type, extra, comment)) 312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return index 313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def AppendRestriction(self, first, second): 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) r = (str(first), str(second)) 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not r in self.ranges: 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.ranges[r] = len(self.restriction_nodes) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.restriction_nodes.append(r) 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.ranges[r] 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def GetSimpleType(self, name): 322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.simple_types[name] == None: 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.simple_types[name] = self.AppendSchema( 324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) SIMPLE_SCHEMA_NAME_MAP[name], 325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) -1, 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'simple type: ' + name) 327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.simple_types[name] 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def GetStringList(self): 330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if self.stringlist_type == None: 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.stringlist_type = self.AppendSchema( 332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'TYPE_LIST', 333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.GetSimpleType('string'), 334f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'simple type: stringlist') 335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.stringlist_type 336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def SchemaHaveRestriction(self, schema): 338c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return any(keyword in schema for keyword in 339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ['minimum', 'maximum', 'enum', 'pattern']) 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def IsConsecutiveInterval(self, seq): 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sortedSeq = sorted(seq) 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return all(sortedSeq[i] + 1 == sortedSeq[i + 1] 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for i in xrange(len(sortedSeq) - 1)) 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def GetEnumIntegerType(self, schema, name): 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert all(type(x) == int for x in schema['enum']) 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) possible_values = schema['enum'] 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.IsConsecutiveInterval(possible_values): 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) index = self.AppendRestriction(max(possible_values), min(possible_values)) 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.AppendSchema('TYPE_INTEGER', index, 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'integer with enumeration restriction (use range instead): %s' % name) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset_begin = len(self.int_enums) 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.int_enums += possible_values 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset_end = len(self.int_enums) 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.AppendSchema('TYPE_INTEGER', 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.AppendRestriction(offset_begin, offset_end), 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'integer with enumeration restriction: %s' % name) 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def GetEnumStringType(self, schema, name): 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert all(type(x) == str for x in schema['enum']) 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset_begin = len(self.string_enums) 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.string_enums += schema['enum'] 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offset_end = len(self.string_enums) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.AppendSchema('TYPE_STRING', 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self.AppendRestriction(offset_begin, offset_end), 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'string with enumeration restriction: %s' % name) 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def GetEnumType(self, schema, name): 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if len(schema['enum']) == 0: 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise RuntimeError('Empty enumeration in %s' % name) 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif schema['type'] == 'integer': 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.GetEnumIntegerType(schema, name) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif schema['type'] == 'string': 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.GetEnumStringType(schema, name) 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise RuntimeError('Unknown enumeration type in %s' % name) 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 379c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def GetPatternType(self, schema, name): 380c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if schema['type'] != 'string': 381c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise RuntimeError('Unknown pattern type in %s' % name) 382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pattern = schema['pattern'] 383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # Try to compile the pattern to validate it, note that the syntax used 384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # here might be slightly different from re2. 385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch # TODO(binjin): Add a python wrapper of re2 and use it here. 386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch re.compile(pattern) 387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch index = len(self.string_enums); 388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.string_enums.append(pattern); 389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.AppendSchema('TYPE_STRING', 390c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.AppendRestriction(index, index), 391c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 'string with pattern restriction: %s' % name); 392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def GetRangedType(self, schema, name): 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if schema['type'] != 'integer': 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise RuntimeError('Unknown ranged type in %s' % name) 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) min_value_set, max_value_set = False, False 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if 'minimum' in schema: 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) min_value = int(schema['minimum']) 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) min_value_set = True 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if 'maximum' in schema: 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) max_value = int(schema['minimum']) 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) max_value_set = True 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if min_value_set and max_value_set and min_value > max_value: 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) raise RuntimeError('Invalid ranged type in %s' % name) 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) index = self.AppendRestriction( 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) str(max_value) if max_value_set else 'INT_MAX', 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) str(min_value) if min_value_set else 'INT_MIN') 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.AppendSchema('TYPE_INTEGER', 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) index, 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 'integer with ranged restriction: %s' % name) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Generate(self, schema, name): 413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Generates the structs for the given schema. 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) |schema|: a valid JSON schema in a dictionary. 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) |name|: the name of the current node, for the generated comments.""" 417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if schema.has_key('$ref'): 418c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if schema.has_key('id'): 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise RuntimeError("Schemas with a $ref can't have an id") 420c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if not isinstance(schema['$ref'], types.StringTypes): 421c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise RuntimeError("$ref attribute must be a string") 422c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return schema['$ref'] 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if schema['type'] in self.simple_types: 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if not self.SchemaHaveRestriction(schema): 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) # Simple types use shared nodes. 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.GetSimpleType(schema['type']) 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) elif 'enum' in schema: 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.GetEnumType(schema, name) 429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch elif 'pattern' in schema: 430c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.GetPatternType(schema, name) 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else: 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return self.GetRangedType(schema, name) 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if schema['type'] == 'array': 435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Special case for lists of strings, which is a common policy type. 43646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) # The 'type' may be missing if the schema has a '$ref' attribute. 43746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if schema['items'].get('type', '') == 'string': 438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return self.GetStringList() 439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.AppendSchema('TYPE_LIST', 440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.GenerateAndCollectID(schema['items'], 'items of ' + name)) 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) elif schema['type'] == 'object': 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Reserve an index first, so that dictionaries come before their 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # properties. This makes sure that the root node is the first in the 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # SchemaNodes array. 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) index = self.AppendSchema('TYPE_DICTIONARY', -1) 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if 'additionalProperties' in schema: 448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch additionalProperties = self.GenerateAndCollectID( 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema['additionalProperties'], 450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'additionalProperties of ' + name) 451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else: 452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) additionalProperties = -1 453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Properties must be sorted by name, for the binary search lookup. 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Note that |properties| must be evaluated immediately, so that all the 456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # recursive calls to Generate() append the necessary child nodes; if 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # |properties| were a generator then this wouldn't work. 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) sorted_properties = sorted(schema.get('properties', {}).items()) 459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch properties = [ 460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (self.GetString(key), self.GenerateAndCollectID(subschema, key)) 461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for key, subschema in sorted_properties ] 462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pattern_properties = [] 464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch for pattern, subschema in schema.get('patternProperties', {}).items(): 465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pattern_properties.append((self.GetString(pattern), 466c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.GenerateAndCollectID(subschema, pattern))); 467c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) begin = len(self.property_nodes) 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.property_nodes += properties 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) end = len(self.property_nodes) 471c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.property_nodes += pattern_properties 472c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch pattern_end = len(self.property_nodes) 473c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if index == 0: 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.root_properties_begin = begin 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.root_properties_end = end 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extra = len(self.properties_nodes) 479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.properties_nodes.append((begin, end, pattern_end, 480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch additionalProperties, name)) 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Set the right data at |index| now. 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) self.schema_nodes[index] = ('TYPE_DICTIONARY', extra, name) 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return index 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) else: 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) assert False 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 488c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def GenerateAndCollectID(self, schema, name): 489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """A wrapper of Generate(), will take the return value, check and add 'id' 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch attribute to self.id_map. The wrapper needs to be used for every call to 491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Generate(). 492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """ 493c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch index = self.Generate(schema, name) 494c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if not schema.has_key('id'): 495c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return index 496c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch id_str = schema['id'] 497c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if self.id_map.has_key(id_str): 498c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise RuntimeError('Duplicated id: ' + id_str) 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.id_map[id_str] = index 500c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return index 501c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) def Write(self, f): 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) """Writes the generated structs to the given file. 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) |f| an open file to write to.""" 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('const internal::SchemaNode kSchemas[] = {\n' 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '// Type Extra\n') 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for type, extra, comment in self.schema_nodes: 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) type += ',' 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write(' { base::Value::%-18s %3d }, // %s\n' % (type, extra, comment)) 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('};\n\n') 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.property_nodes: 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('const internal::PropertyNode kPropertyNodes[] = {\n' 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '// Property #Schema\n') 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for key, schema in self.property_nodes: 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key += ',' 5185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' { %-50s %6d },\n' % (key, schema)) 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.properties_nodes: 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('const internal::PropertiesNode kProperties[] = {\n' 523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch '// Begin End PatternEnd Additional Properties\n') 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for node in self.properties_nodes: 525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch f.write(' { %5d, %5d, %10d, %5d }, // %s\n' % node) 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.restriction_nodes: 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('const internal::RestrictionNode kRestrictionNodes[] = {\n') 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('// FIRST, SECOND\n') 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for first, second in self.restriction_nodes: 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' {{ %-8s %4s}},\n' % (first + ',', second)) 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.int_enums: 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('const int kIntegerEnumerations[] = {\n') 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for possible_values in self.int_enums: 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' %d,\n' % possible_values) 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if self.string_enums: 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('const char* kStringEnumerations[] = {\n') 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for possible_values in self.string_enums: 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' %s,\n' % self.GetString(possible_values)) 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('const internal::SchemaData kChromeSchemaData = {\n' 5485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ' kSchemas,\n') 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' kPropertyNodes,\n' if self.property_nodes else ' NULL,\n') 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' kProperties,\n' if self.properties_nodes else ' NULL,\n') 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' kRestrictionNodes,\n' if self.restriction_nodes else ' NULL,\n') 5525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' kIntegerEnumerations,\n' if self.int_enums else ' NULL,\n') 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write(' kStringEnumerations,\n' if self.string_enums else ' NULL,\n') 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f.write('};\n\n') 5553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 556c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def GetByID(self, id_str): 557c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if not isinstance(id_str, types.StringTypes): 558c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return id_str 559c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if not self.id_map.has_key(id_str): 560c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch raise RuntimeError('Invalid $ref: ' + id_str) 561c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return self.id_map[id_str] 562c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 563c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def ResolveID(self, index, params): 564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return params[:index] + (self.GetByID(params[index]),) + params[index+1:] 565c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch def ResolveReferences(self): 567c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """Resolve reference mapping, required to be called after Generate() 568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 569c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch After calling Generate(), the type of indices used in schema structures 570c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch might be either int or string. An int type suggests that it's a resolved 571c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch index, but for string type it's unresolved. Resolving a reference is as 572c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch simple as looking up for corresponding ID in self.id_map, and replace the 573c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch old index with the mapped index. 574c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch """ 575c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.schema_nodes = map(partial(self.ResolveID, 1), self.schema_nodes) 576c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.property_nodes = map(partial(self.ResolveID, 1), self.property_nodes) 577c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.properties_nodes = map(partial(self.ResolveID, 3), 578c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch self.properties_nodes) 5793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WritePolicyConstantSource(policies, os, f): 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('#include "policy/policy_constants.h"\n' 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n' 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '#include <algorithm>\n' 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) '#include <climits>\n' 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n' 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#include "base/logging.h"\n' 587f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '#include "components/policy/core/common/schema_internal.h"\n' 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '\n' 589f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'namespace policy {\n' 590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n' 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'namespace {\n' 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '\n') 593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Generate the Chrome schema. 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome_schema = { 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'type': 'object', 597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'properties': {}, 598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shared_strings = {} 600f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for policy in policies: 601f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) shared_strings[policy.name] = "key::k%s" % policy.name 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if policy.is_supported: 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome_schema['properties'][policy.name] = policy.schema 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Note: this list must be kept in sync with the known property list of the 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # Chrome schema, so that binary seaching in the PropertyNode array gets the 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # right index on this array as well. See the implementation of 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) # GetChromePolicyDetails() below. 609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('const PolicyDetails kChromePolicyDetails[] = {\n' 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '// is_deprecated is_device_policy id max_external_data_size\n') 611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if policy.is_supported: 613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write(' { %-14s %-16s %3s, %24s },\n' % ( 614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'true,' if policy.is_deprecated else 'false,', 615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'true,' if policy.is_device_only else 'false,', 616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) policy.id, 617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) policy.max_size)) 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('};\n\n') 619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_generator = SchemaNodesGenerator(shared_strings) 621c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch schema_generator.GenerateAndCollectID(chrome_schema, 'root node') 622c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch schema_generator.ResolveReferences() 623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_generator.Write(f) 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 625f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('bool CompareKeys(const internal::PropertyNode& node,\n' 626f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' const std::string& key) {\n' 627f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' return node.key < key;\n' 628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) '}\n\n') 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('} // namespace\n\n') 631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if os == 'win': 633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('#if defined(GOOGLE_CHROME_BUILD)\n' 634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'const wchar_t kRegistryChromePolicyKey[] = ' 635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'L"' + CHROME_POLICY_KEY + '";\n' 636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#else\n' 637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'const wchar_t kRegistryChromePolicyKey[] = ' 638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'L"' + CHROMIUM_POLICY_KEY + '";\n' 639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '#endif\n\n') 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 641f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('const internal::SchemaData* GetChromeSchemaData() {\n' 642f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' return &kChromeSchemaData;\n' 643868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) '}\n\n') 644868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci f.write('#if defined (OS_CHROMEOS)\n' 6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'void SetEnterpriseUsersDefaults(PolicyMap* policy_map) {\n') 6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for policy in policies: 6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if policy.has_enterprise_default: 6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if policy.policy_type == 'TYPE_BOOLEAN': 6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci creation_expression = 'new base::FundamentalValue(%s)' %\ 6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ('true' if policy.enterprise_default else 'false') 6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci elif policy.policy_type == 'TYPE_INTEGER': 6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci creation_expression = 'new base::FundamentalValue(%s)' %\ 6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci policy.enterprise_default 6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci elif policy.policy_type == 'TYPE_STRING': 6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci creation_expression = 'new base::StringValue("%s")' %\ 6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci policy.enterprise_default 6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci else: 6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci raise RuntimeError('Type %s of policy %s is not supported at ' 6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'enterprise defaults' % (policy.policy_type, 6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci policy.name)) 6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci f.write(' if (!policy_map->Get(key::k%s)) {\n' 6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' policy_map->Set(key::k%s,\n' 6651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' POLICY_LEVEL_MANDATORY,\n' 6661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' POLICY_SCOPE_USER,\n' 6671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' %s,\n' 6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' NULL);\n' 6691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ' }\n' % (policy.name, policy.name, creation_expression)) 6701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci f.write('}\n' 6721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci '#endif\n\n') 6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 674f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write('const PolicyDetails* GetChromePolicyDetails(' 675f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 'const std::string& policy) {\n' 676f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // First index in kPropertyNodes of the Chrome policies.\n' 677f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' static const int begin_index = %s;\n' 678f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // One-past-the-end of the Chrome policies in kPropertyNodes.\n' 679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' static const int end_index = %s;\n' % 680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (schema_generator.root_properties_begin, 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) schema_generator.root_properties_end)) 682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f.write(' const internal::PropertyNode* begin =\n' 683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' kPropertyNodes + begin_index;\n' 684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' const internal::PropertyNode* end = kPropertyNodes + end_index;\n' 685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' const internal::PropertyNode* it =\n' 686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' std::lower_bound(begin, end, policy, CompareKeys);\n' 687f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' if (it == end || it->key != policy)\n' 688f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' return NULL;\n' 689f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // This relies on kPropertyNodes from begin_index to end_index\n' 690f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // having exactly the same policies (and in the same order) as\n' 691f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // kChromePolicyDetails, so that binary searching on the first\n' 692f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // gets the same results as a binary search on the second would.\n' 693f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // However, kPropertyNodes has the policy names and\n' 694f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // kChromePolicyDetails doesn\'t, so we obtain the index into\n' 695f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // the second array by searching the first to avoid duplicating\n' 696f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // the policy name pointers.\n' 697f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // Offsetting |it| from |begin| here obtains the index we\'re\n' 698f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' // looking for.\n' 699f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' size_t index = it - begin;\n' 700f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' CHECK_LT(index, arraysize(kChromePolicyDetails));\n' 701f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ' return kChromePolicyDetails + index;\n' 702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '}\n\n') 703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('namespace key {\n\n') 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # TODO(joaodasilva): Include only supported policies in 707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # configuration_policy_handler.cc and configuration_policy_handler_list.cc 708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # so that these names can be conditional on 'policy.is_supported'. 709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # http://crbug.com/223616 710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('const char k{name}[] = "{name}";\n'.format(name=policy.name)) 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('\n} // namespace key\n\n' 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '} // namespace policy\n') 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#------------------ policy protobufs --------------------------------# 716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CHROME_SETTINGS_PROTO_HEAD = ''' 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syntax = "proto2"; 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)option optimize_for = LITE_RUNTIME; 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)package enterprise_management; 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// For StringList and PolicyOptions. 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import "cloud_policy.proto"; 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)''' 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CLOUD_POLICY_PROTO_HEAD = ''' 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syntax = "proto2"; 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)option optimize_for = LITE_RUNTIME; 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package enterprise_management; 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)message StringList { 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) repeated string entries = 1; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)message PolicyOptions { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum PolicyMode { 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The given settings are applied regardless of user choice. 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MANDATORY = 0; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user may choose to override the given settings. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RECOMMENDED = 1; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No policy value is present and the policy should be ignored. 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UNSET = 2; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) optional PolicyMode mode = 1 [default = MANDATORY]; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)message BooleanPolicyProto { 7542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional PolicyOptions policy_options = 1; 7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional bool value = 2; 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)message IntegerPolicyProto { 7592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional PolicyOptions policy_options = 1; 7602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional int64 value = 2; 7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)message StringPolicyProto { 7642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional PolicyOptions policy_options = 1; 7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional string value = 2; 7662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)message StringListPolicyProto { 7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional PolicyOptions policy_options = 1; 7702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) optional StringList value = 2; 7712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Field IDs [1..RESERVED_IDS] will not be used in the wrapping protobuf. 777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)RESERVED_IDS = 2 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WritePolicyProto(f, policy, fields): 781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) _OutputComment(f, policy.caption + '\n\n' + policy.desc) 782a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if policy.items is not None: 783a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) _OutputComment(f, '\nValid values:') 784a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for item in policy.items: 7852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch _OutputComment(f, ' %s: %s' % (str(item.value), item.caption)) 786ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if policy.policy_type == 'TYPE_DICTIONARY': 787ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch _OutputComment(f, '\nValue schema:\n%s' % 788ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch json.dumps(policy.schema, sort_keys=True, indent=4, 789ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch separators=(',', ': '))) 790ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch _OutputComment(f, '\nSupported on: %s' % ', '.join(policy.platforms)) 7911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if policy.can_be_recommended and not policy.can_be_mandatory: 7921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _OutputComment(f, '\nNote: this policy must have a RECOMMENDED ' +\ 7931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'PolicyMode set in PolicyOptions.') 794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('message %sProto {\n' % policy.name) 795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' optional PolicyOptions policy_options = 1;\n') 796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' optional %s %s = 2;\n' % (policy.protobuf_type, policy.name)) 797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('}\n\n') 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fields += [ ' optional %sProto %s = %s;\n' % 799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (policy.name, policy.name, policy.id + RESERVED_IDS) ] 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WriteChromeSettingsProtobuf(policies, os, f): 803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(CHROME_SETTINGS_PROTO_HEAD) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fields = [] 806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('// PBs for individual settings.\n\n') 807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # Note: this protobuf also gets the unsupported policies, since it's an 809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) # exaustive list of all the supported user policies on any platform. 810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if not policy.is_device_only: 8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _WritePolicyProto(f, policy, fields) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 813c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('// --------------------------------------------------\n' 814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) '// Big wrapper PB containing the above groups.\n\n' 815c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 'message ChromeSettingsProto {\n') 816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(''.join(fields)) 817c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('}\n\n') 818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WriteCloudPolicyProtobuf(policies, os, f): 821c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(CLOUD_POLICY_PROTO_HEAD) 822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('message CloudPolicySettings {\n') 823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 824c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if policy.is_supported and not policy.is_device_only: 8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) f.write(' optional %sPolicyProto %s = %s;\n' % 826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (policy.policy_protobuf_type, policy.name, 827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy.id + RESERVED_IDS)) 828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write('}\n\n') 8292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#------------------ protobuf decoder -------------------------------# 832c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CPP_HEAD = ''' 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8379ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/basictypes.h" 8387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/callback.h" 8399ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/json/json_reader.h" 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 8419ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/memory/scoped_ptr.h" 8423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "base/memory/weak_ptr.h" 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 844a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_external_data_manager.h" 845f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/external_data_fetcher.h" 846f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "components/policy/core/common/policy_map.h" 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "policy/policy_constants.h" 8482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "policy/proto/cloud_policy.pb.h" 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using google::protobuf::RepeatedPtrField; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace policy { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace em = enterprise_management; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::Value* DecodeIntegerValue(google::protobuf::int64 value) { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value < std::numeric_limits<int>::min() || 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value > std::numeric_limits<int>::max()) { 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Integer value " << value 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " out of numeric limits, ignoring."; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 864116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return new base::FundamentalValue(static_cast<int>(value)); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 867eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbase::ListValue* DecodeStringList(const em::StringList& string_list) { 868eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::ListValue* list_value = new base::ListValue; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RepeatedPtrField<std::string>::const_iterator entry; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (entry = string_list.entries().begin(); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry != string_list.entries().end(); ++entry) { 8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) list_value->AppendString(*entry); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return list_value; 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 877d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbase::Value* DecodeJson(const std::string& json) { 8789ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch scoped_ptr<base::Value> root( 8799ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS)); 880d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 881d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (!root) 8829ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch LOG(WARNING) << "Invalid JSON string, ignoring: " << json; 8839ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 884d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Accept any Value type that parsed as JSON, and leave it to the handler to 885d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // convert and check the concrete type. 886d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return root.release(); 8879ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch} 8889ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch 8893240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid DecodePolicy(const em::CloudPolicySettings& policy, 8903240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch base::WeakPtr<CloudExternalDataManager> external_data_manager, 8913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch PolicyMap* map) { 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CPP_FOOT = '''} 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)''' 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def _CreateValue(type, arg): 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if type == 'TYPE_BOOLEAN': 903116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return 'new base::FundamentalValue(%s)' % arg 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) elif type == 'TYPE_INTEGER': 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 'DecodeIntegerValue(%s)' % arg 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) elif type == 'TYPE_STRING': 9075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 'new base::StringValue(%s)' % arg 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) elif type == 'TYPE_LIST': 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return 'DecodeStringList(%s)' % arg 9103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch elif type == 'TYPE_DICTIONARY' or type == 'TYPE_EXTERNAL': 911d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return 'DecodeJson(%s)' % arg 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) raise NotImplementedError('Unknown type %s' % type) 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochdef _CreateExternalDataFetcher(type, name): 9173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if type == 'TYPE_EXTERNAL': 9183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return 'new ExternalDataFetcher(external_data_manager, key::k%s)' % name 9193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch return 'NULL' 9203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 9213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WritePolicyCode(f, policy): 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) membername = policy.name.lower() 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) proto_type = '%sPolicyProto' % policy.policy_protobuf_type 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' if (policy.has_%s()) {\n' % membername) 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' const em::%s& policy_proto = policy.%s();\n' % 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (proto_type, membername)) 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' if (policy_proto.has_value()) {\n') 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(' PolicyLevel level = POLICY_LEVEL_MANDATORY;\n' 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' bool do_set = true;\n' 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' if (policy_proto.has_policy_options()) {\n' 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' do_set = false;\n' 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' switch(policy_proto.policy_options().mode()) {\n' 934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' case em::PolicyOptions::MANDATORY:\n' 935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' do_set = true;\n' 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' level = POLICY_LEVEL_MANDATORY;\n' 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' break;\n' 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' case em::PolicyOptions::RECOMMENDED:\n' 939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' do_set = true;\n' 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' level = POLICY_LEVEL_RECOMMENDED;\n' 941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' break;\n' 942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' case em::PolicyOptions::UNSET:\n' 943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' break;\n' 944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' }\n' 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' }\n' 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' if (do_set) {\n') 947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch f.write(' base::Value* value = %s;\n' % 9483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch (_CreateValue(policy.policy_type, 'policy_proto.value()'))) 949a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # TODO(bartfab): |value| == NULL indicates that the policy value could not be 950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # parsed successfully. Surface such errors in the UI. 951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) f.write(' if (value) {\n') 952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) f.write(' ExternalDataFetcher* external_data_fetcher = %s;\n' % 9533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch _CreateExternalDataFetcher(policy.policy_type, policy.name)) 954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) f.write(' map->Set(key::k%s, level, POLICY_SCOPE_USER,\n' % 955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) policy.name) 956a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) f.write(' value, external_data_fetcher);\n' 957a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ' }\n' 958a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ' }\n' 959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' }\n' 960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ' }\n') 961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WriteCloudPolicyDecoder(policies, os, f): 964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(CPP_HEAD) 965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for policy in policies: 966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if policy.is_supported and not policy.is_device_only: 9672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) _WritePolicyCode(f, policy) 968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) f.write(CPP_FOOT) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sys.exit(main()) 973