| Index: chrome/tools/build/generate_policy_source.py
|
| diff --git a/chrome/tools/build/generate_policy_source.py b/chrome/tools/build/generate_policy_source.py
|
| deleted file mode 100755
|
| index 315650de2510ed9de2adaabfd24361db4e36c3d3..0000000000000000000000000000000000000000
|
| --- a/chrome/tools/build/generate_policy_source.py
|
| +++ /dev/null
|
| @@ -1,748 +0,0 @@
|
| -#!/usr/bin/env python
|
| -# Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -'''python %prog [options] platform chromium_os_flag template
|
| -
|
| -platform specifies which platform source is being generated for
|
| - and can be one of (win, mac, linux)
|
| -chromium_os_flag should be 1 if this is a Chromium OS build
|
| -template is the path to a .json policy template file.'''
|
| -
|
| -from __future__ import with_statement
|
| -import json
|
| -from optparse import OptionParser
|
| -import re
|
| -import sys
|
| -import textwrap
|
| -
|
| -
|
| -CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome'
|
| -CHROMIUM_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Chromium'
|
| -
|
| -
|
| -class PolicyDetails:
|
| - """Parses a policy template and caches all its details."""
|
| -
|
| - # Maps policy types to a tuple with 3 other types:
|
| - # - the equivalent base::Value::Type or 'TYPE_EXTERNAL' if the policy
|
| - # references external data
|
| - # - the equivalent Protobuf field type
|
| - # - the name of one of the protobufs for shared policy types
|
| - # TODO(joaodasilva): refactor the 'dict' type into a more generic 'json' type
|
| - # that can also be used to represent lists of other JSON objects.
|
| - TYPE_MAP = {
|
| - 'dict': ('TYPE_DICTIONARY', 'string', 'String'),
|
| - 'external': ('TYPE_EXTERNAL', 'string', 'String'),
|
| - 'int': ('TYPE_INTEGER', 'int64', 'Integer'),
|
| - 'int-enum': ('TYPE_INTEGER', 'int64', 'Integer'),
|
| - 'list': ('TYPE_LIST', 'StringList', 'StringList'),
|
| - 'main': ('TYPE_BOOLEAN', 'bool', 'Boolean'),
|
| - 'string': ('TYPE_STRING', 'string', 'String'),
|
| - 'string-enum': ('TYPE_STRING', 'string', 'String'),
|
| - }
|
| -
|
| - class EnumItem:
|
| - def __init__(self, item):
|
| - self.caption = PolicyDetails._RemovePlaceholders(item['caption'])
|
| - self.value = item['value']
|
| -
|
| - def __init__(self, policy, os, is_chromium_os):
|
| - self.id = policy['id']
|
| - self.name = policy['name']
|
| - self.is_deprecated = policy.get('deprecated', False)
|
| - self.is_device_only = policy.get('device_only', False)
|
| - self.schema = policy.get('schema', {})
|
| -
|
| - expected_platform = 'chrome_os' if is_chromium_os else os.lower()
|
| - self.platforms = []
|
| - for platform, version in [ p.split(':') for p in policy['supported_on'] ]:
|
| - if not version.endswith('-'):
|
| - continue
|
| -
|
| - if platform.startswith('chrome.'):
|
| - platform_sub = platform[7:]
|
| - if platform_sub == '*':
|
| - self.platforms.extend(['win', 'mac', 'linux'])
|
| - else:
|
| - self.platforms.append(platform_sub)
|
| - else:
|
| - self.platforms.append(platform)
|
| -
|
| - self.platforms.sort()
|
| - self.is_supported = expected_platform in self.platforms
|
| -
|
| - if not PolicyDetails.TYPE_MAP.has_key(policy['type']):
|
| - raise NotImplementedError('Unknown policy type for %s: %s' %
|
| - (policy['name'], policy['type']))
|
| - self.policy_type, self.protobuf_type, self.policy_protobuf_type = \
|
| - PolicyDetails.TYPE_MAP[policy['type']]
|
| - self.schema = policy['schema']
|
| -
|
| - self.desc = '\n'.join(
|
| - map(str.strip,
|
| - PolicyDetails._RemovePlaceholders(policy['desc']).splitlines()))
|
| - self.caption = PolicyDetails._RemovePlaceholders(policy['caption'])
|
| - self.max_size = policy.get('max_size', 0)
|
| -
|
| - items = policy.get('items')
|
| - if items is None:
|
| - self.items = None
|
| - else:
|
| - self.items = [ PolicyDetails.EnumItem(entry) for entry in items ]
|
| -
|
| - PH_PATTERN = re.compile('<ph[^>]*>([^<]*|[^<]*<ex>([^<]*)</ex>[^<]*)</ph>')
|
| -
|
| - # Simplistic grit placeholder stripper.
|
| - @staticmethod
|
| - def _RemovePlaceholders(text):
|
| - result = ''
|
| - pos = 0
|
| - for m in PolicyDetails.PH_PATTERN.finditer(text):
|
| - result += text[pos:m.start(0)]
|
| - result += m.group(2) or m.group(1)
|
| - pos = m.end(0)
|
| - result += text[pos:]
|
| - return result
|
| -
|
| -
|
| -def main():
|
| - parser = OptionParser(usage=__doc__)
|
| - parser.add_option('--pch', '--policy-constants-header', dest='header_path',
|
| - help='generate header file of policy constants',
|
| - metavar='FILE')
|
| - parser.add_option('--pcc', '--policy-constants-source', dest='source_path',
|
| - help='generate source file of policy constants',
|
| - metavar='FILE')
|
| - parser.add_option('--cpp', '--cloud-policy-protobuf',
|
| - dest='cloud_policy_proto_path',
|
| - help='generate cloud policy protobuf file',
|
| - metavar='FILE')
|
| - parser.add_option('--csp', '--chrome-settings-protobuf',
|
| - dest='chrome_settings_proto_path',
|
| - help='generate chrome settings protobuf file',
|
| - metavar='FILE')
|
| - parser.add_option('--cpd', '--cloud-policy-decoder',
|
| - dest='cloud_policy_decoder_path',
|
| - help='generate C++ code decoding the cloud policy protobuf',
|
| - metavar='FILE')
|
| -
|
| - (opts, args) = parser.parse_args()
|
| -
|
| - if len(args) != 3:
|
| - print 'exactly platform, chromium_os flag and input file must be specified.'
|
| - parser.print_help()
|
| - return 2
|
| -
|
| - os = args[0]
|
| - is_chromium_os = args[1] == '1'
|
| - template_file_name = args[2]
|
| -
|
| - template_file_contents = _LoadJSONFile(template_file_name)
|
| - policy_details = [ PolicyDetails(policy, os, is_chromium_os)
|
| - for policy in _Flatten(template_file_contents) ]
|
| - sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name)
|
| -
|
| - def GenerateFile(path, writer, sorted=False):
|
| - if path:
|
| - with open(path, 'w') as f:
|
| - _OutputGeneratedWarningHeader(f, template_file_name)
|
| - writer(sorted and sorted_policy_details or policy_details, os, f)
|
| -
|
| - GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True)
|
| - GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True)
|
| - GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf)
|
| - GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf)
|
| - GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder)
|
| -
|
| - return 0
|
| -
|
| -
|
| -#------------------ shared helpers ---------------------------------#
|
| -
|
| -def _OutputGeneratedWarningHeader(f, template_file_path):
|
| - f.write('//\n'
|
| - '// DO NOT MODIFY THIS FILE DIRECTLY!\n'
|
| - '// IT IS GENERATED BY generate_policy_source.py\n'
|
| - '// FROM ' + template_file_path + '\n'
|
| - '//\n\n')
|
| -
|
| -
|
| -COMMENT_WRAPPER = textwrap.TextWrapper()
|
| -COMMENT_WRAPPER.width = 80
|
| -COMMENT_WRAPPER.initial_indent = '// '
|
| -COMMENT_WRAPPER.subsequent_indent = '// '
|
| -COMMENT_WRAPPER.replace_whitespace = False
|
| -
|
| -
|
| -# Writes a comment, each line prefixed by // and wrapped to 80 spaces.
|
| -def _OutputComment(f, comment):
|
| - for line in comment.splitlines():
|
| - if len(line) == 0:
|
| - f.write('//')
|
| - else:
|
| - f.write(COMMENT_WRAPPER.fill(line))
|
| - f.write('\n')
|
| -
|
| -
|
| -# Returns an iterator over all the policies in |template_file_contents|.
|
| -def _Flatten(template_file_contents):
|
| - for policy in template_file_contents['policy_definitions']:
|
| - if policy['type'] == 'group':
|
| - for sub_policy in policy['policies']:
|
| - yield sub_policy
|
| - else:
|
| - yield policy
|
| -
|
| -
|
| -def _LoadJSONFile(json_file):
|
| - with open(json_file, 'r') as f:
|
| - text = f.read()
|
| - return eval(text)
|
| -
|
| -
|
| -#------------------ policy constants header ------------------------#
|
| -
|
| -def _WritePolicyConstantHeader(policies, os, f):
|
| - f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n'
|
| - '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n'
|
| - '\n'
|
| - '#include <string>\n'
|
| - '\n'
|
| - '#include "base/basictypes.h"\n'
|
| - '#include "base/values.h"\n'
|
| - '#include "components/policy/core/common/policy_details.h"\n'
|
| - '\n'
|
| - 'namespace policy {\n'
|
| - '\n'
|
| - 'namespace internal {\n'
|
| - 'struct SchemaData;\n'
|
| - '}\n\n')
|
| -
|
| - if os == 'win':
|
| - f.write('// The windows registry path where Chrome policy '
|
| - 'configuration resides.\n'
|
| - 'extern const wchar_t kRegistryChromePolicyKey[];\n')
|
| -
|
| - f.write('// Returns the PolicyDetails for |policy| if |policy| is a known\n'
|
| - '// Chrome policy, otherwise returns NULL.\n'
|
| - 'const PolicyDetails* GetChromePolicyDetails('
|
| - 'const std::string& policy);\n'
|
| - '\n'
|
| - '// Returns the schema data of the Chrome policy schema.\n'
|
| - 'const internal::SchemaData* GetChromeSchemaData();\n'
|
| - '\n')
|
| - f.write('// Key names for the policy settings.\n'
|
| - 'namespace key {\n\n')
|
| - for policy in policies:
|
| - # TODO(joaodasilva): Include only supported policies in
|
| - # configuration_policy_handler.cc and configuration_policy_handler_list.cc
|
| - # so that these names can be conditional on 'policy.is_supported'.
|
| - # http://crbug.com/223616
|
| - f.write('extern const char k' + policy.name + '[];\n')
|
| - f.write('\n} // namespace key\n\n'
|
| - '} // namespace policy\n\n'
|
| - '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n')
|
| -
|
| -
|
| -#------------------ policy constants source ------------------------#
|
| -
|
| -# A mapping of the simple schema types to base::Value::Types.
|
| -SIMPLE_SCHEMA_NAME_MAP = {
|
| - 'boolean': 'TYPE_BOOLEAN',
|
| - 'integer': 'TYPE_INTEGER',
|
| - 'null' : 'TYPE_NULL',
|
| - 'number' : 'TYPE_DOUBLE',
|
| - 'string' : 'TYPE_STRING',
|
| -}
|
| -
|
| -
|
| -class SchemaNodesGenerator:
|
| - """Builds the internal structs to represent a JSON schema."""
|
| -
|
| - def __init__(self, shared_strings):
|
| - """Creates a new generator.
|
| -
|
| - |shared_strings| is a map of strings to a C expression that evaluates to
|
| - that string at runtime. This mapping can be used to reuse existing string
|
| - constants."""
|
| - self.shared_strings = shared_strings
|
| - self.schema_nodes = []
|
| - self.property_nodes = []
|
| - self.properties_nodes = []
|
| - self.simple_types = {
|
| - 'boolean': None,
|
| - 'integer': None,
|
| - 'null': None,
|
| - 'number': None,
|
| - 'string': None,
|
| - }
|
| - self.stringlist_type = None
|
| -
|
| - def GetString(self, s):
|
| - return self.shared_strings[s] if s in self.shared_strings else '"%s"' % s
|
| -
|
| - def AppendSchema(self, type, extra, comment=''):
|
| - index = len(self.schema_nodes)
|
| - self.schema_nodes.append((type, extra, comment))
|
| - return index
|
| -
|
| - def GetSimpleType(self, name):
|
| - if self.simple_types[name] == None:
|
| - self.simple_types[name] = self.AppendSchema(
|
| - SIMPLE_SCHEMA_NAME_MAP[name],
|
| - -1,
|
| - 'simple type: ' + name)
|
| - return self.simple_types[name]
|
| -
|
| - def GetStringList(self):
|
| - if self.stringlist_type == None:
|
| - self.stringlist_type = self.AppendSchema(
|
| - 'TYPE_LIST',
|
| - self.GetSimpleType('string'),
|
| - 'simple type: stringlist')
|
| - return self.stringlist_type
|
| -
|
| - def Generate(self, schema, name):
|
| - """Generates the structs for the given schema.
|
| -
|
| - |schema|: a valid JSON schema in a dictionary.
|
| - |name|: the name of the current node, for the generated comments."""
|
| - # Simple types use shared nodes.
|
| - if schema['type'] in self.simple_types:
|
| - return self.GetSimpleType(schema['type'])
|
| -
|
| - if schema['type'] == 'array':
|
| - # Special case for lists of strings, which is a common policy type.
|
| - if schema['items']['type'] == 'string':
|
| - return self.GetStringList()
|
| - return self.AppendSchema(
|
| - 'TYPE_LIST',
|
| - self.Generate(schema['items'], 'items of ' + name))
|
| - elif schema['type'] == 'object':
|
| - # Reserve an index first, so that dictionaries come before their
|
| - # properties. This makes sure that the root node is the first in the
|
| - # SchemaNodes array.
|
| - index = self.AppendSchema('TYPE_DICTIONARY', -1)
|
| -
|
| - if 'additionalProperties' in schema:
|
| - additionalProperties = self.Generate(
|
| - schema['additionalProperties'],
|
| - 'additionalProperties of ' + name)
|
| - else:
|
| - additionalProperties = -1
|
| -
|
| - # Properties must be sorted by name, for the binary search lookup.
|
| - # Note that |properties| must be evaluated immediately, so that all the
|
| - # recursive calls to Generate() append the necessary child nodes; if
|
| - # |properties| were a generator then this wouldn't work.
|
| - sorted_properties = sorted(schema.get('properties', {}).items())
|
| - properties = [ (self.GetString(key), self.Generate(schema, key))
|
| - for key, schema in sorted_properties ]
|
| - begin = len(self.property_nodes)
|
| - self.property_nodes += properties
|
| - end = len(self.property_nodes)
|
| - if index == 0:
|
| - self.root_properties_begin = begin
|
| - self.root_properties_end = end
|
| -
|
| - extra = len(self.properties_nodes)
|
| - self.properties_nodes.append((begin, end, additionalProperties, name))
|
| -
|
| - # Set the right data at |index| now.
|
| - self.schema_nodes[index] = ('TYPE_DICTIONARY', extra, name)
|
| - return index
|
| - else:
|
| - assert False
|
| -
|
| - def Write(self, f):
|
| - """Writes the generated structs to the given file.
|
| -
|
| - |f| an open file to write to."""
|
| - f.write('const internal::SchemaNode kSchemas[] = {\n'
|
| - '// Type Extra\n')
|
| - for type, extra, comment in self.schema_nodes:
|
| - type += ','
|
| - f.write(' { base::Value::%-18s %3d }, // %s\n' % (type, extra, comment))
|
| - f.write('};\n\n')
|
| -
|
| - f.write('const internal::PropertyNode kPropertyNodes[] = {\n'
|
| - '// Property #Schema\n')
|
| - for key, schema in self.property_nodes:
|
| - key += ','
|
| - f.write(' { %-50s %7d },\n' % (key, schema))
|
| - f.write('};\n\n')
|
| -
|
| - f.write('const internal::PropertiesNode kProperties[] = {\n'
|
| - '// Begin End Additional Properties\n')
|
| - for node in self.properties_nodes:
|
| - f.write(' { %5d, %5d, %5d }, // %s\n' % node)
|
| - f.write('};\n\n')
|
| -
|
| - f.write('const internal::SchemaData kChromeSchemaData = {\n'
|
| - ' kSchemas,\n'
|
| - ' kPropertyNodes,\n'
|
| - ' kProperties,\n'
|
| - '};\n\n')
|
| -
|
| -
|
| -def _WritePolicyConstantSource(policies, os, f):
|
| - f.write('#include "policy/policy_constants.h"\n'
|
| - '\n'
|
| - '#include <algorithm>\n'
|
| - '\n'
|
| - '#include "base/logging.h"\n'
|
| - '#include "components/policy/core/common/schema_internal.h"\n'
|
| - '\n'
|
| - 'namespace policy {\n'
|
| - '\n'
|
| - 'namespace {\n'
|
| - '\n')
|
| -
|
| - # Generate the Chrome schema.
|
| - chrome_schema = {
|
| - 'type': 'object',
|
| - 'properties': {},
|
| - }
|
| - shared_strings = {}
|
| - for policy in policies:
|
| - shared_strings[policy.name] = "key::k%s" % policy.name
|
| - if policy.is_supported:
|
| - chrome_schema['properties'][policy.name] = policy.schema
|
| -
|
| - # Note: this list must be kept in sync with the known property list of the
|
| - # Chrome schema, so that binary seaching in the PropertyNode array gets the
|
| - # right index on this array as well. See the implementation of
|
| - # GetChromePolicyDetails() below.
|
| - f.write('const PolicyDetails kChromePolicyDetails[] = {\n'
|
| - '// is_deprecated is_device_policy id max_external_data_size\n')
|
| - for policy in policies:
|
| - if policy.is_supported:
|
| - f.write(' { %-14s %-16s %3s, %24s },\n' % (
|
| - 'true,' if policy.is_deprecated else 'false,',
|
| - 'true,' if policy.is_device_only else 'false,',
|
| - policy.id,
|
| - policy.max_size))
|
| - f.write('};\n\n')
|
| -
|
| - schema_generator = SchemaNodesGenerator(shared_strings)
|
| - schema_generator.Generate(chrome_schema, 'root node')
|
| - schema_generator.Write(f)
|
| -
|
| - f.write('bool CompareKeys(const internal::PropertyNode& node,\n'
|
| - ' const std::string& key) {\n'
|
| - ' return node.key < key;\n'
|
| - '}\n\n')
|
| -
|
| - f.write('} // namespace\n\n')
|
| -
|
| - if os == 'win':
|
| - f.write('#if defined(GOOGLE_CHROME_BUILD)\n'
|
| - 'const wchar_t kRegistryChromePolicyKey[] = '
|
| - 'L"' + CHROME_POLICY_KEY + '";\n'
|
| - '#else\n'
|
| - 'const wchar_t kRegistryChromePolicyKey[] = '
|
| - 'L"' + CHROMIUM_POLICY_KEY + '";\n'
|
| - '#endif\n\n')
|
| -
|
| - f.write('const internal::SchemaData* GetChromeSchemaData() {\n'
|
| - ' return &kChromeSchemaData;\n'
|
| - '}\n\n')
|
| -
|
| - f.write('const PolicyDetails* GetChromePolicyDetails('
|
| - 'const std::string& policy) {\n'
|
| - ' // First index in kPropertyNodes of the Chrome policies.\n'
|
| - ' static const int begin_index = %s;\n'
|
| - ' // One-past-the-end of the Chrome policies in kPropertyNodes.\n'
|
| - ' static const int end_index = %s;\n' %
|
| - (schema_generator.root_properties_begin,
|
| - schema_generator.root_properties_end))
|
| - f.write(' const internal::PropertyNode* begin =\n'
|
| - ' kPropertyNodes + begin_index;\n'
|
| - ' const internal::PropertyNode* end = kPropertyNodes + end_index;\n'
|
| - ' const internal::PropertyNode* it =\n'
|
| - ' std::lower_bound(begin, end, policy, CompareKeys);\n'
|
| - ' if (it == end || it->key != policy)\n'
|
| - ' return NULL;\n'
|
| - ' // This relies on kPropertyNodes from begin_index to end_index\n'
|
| - ' // having exactly the same policies (and in the same order) as\n'
|
| - ' // kChromePolicyDetails, so that binary searching on the first\n'
|
| - ' // gets the same results as a binary search on the second would.\n'
|
| - ' // However, kPropertyNodes has the policy names and\n'
|
| - ' // kChromePolicyDetails doesn\'t, so we obtain the index into\n'
|
| - ' // the second array by searching the first to avoid duplicating\n'
|
| - ' // the policy name pointers.\n'
|
| - ' // Offsetting |it| from |begin| here obtains the index we\'re\n'
|
| - ' // looking for.\n'
|
| - ' size_t index = it - begin;\n'
|
| - ' CHECK_LT(index, arraysize(kChromePolicyDetails));\n'
|
| - ' return kChromePolicyDetails + index;\n'
|
| - '}\n\n')
|
| -
|
| - f.write('namespace key {\n\n')
|
| - for policy in policies:
|
| - # TODO(joaodasilva): Include only supported policies in
|
| - # configuration_policy_handler.cc and configuration_policy_handler_list.cc
|
| - # so that these names can be conditional on 'policy.is_supported'.
|
| - # http://crbug.com/223616
|
| - f.write('const char k{name}[] = "{name}";\n'.format(name=policy.name))
|
| - f.write('\n} // namespace key\n\n'
|
| - '} // namespace policy\n')
|
| -
|
| -
|
| -#------------------ policy protobufs --------------------------------#
|
| -
|
| -CHROME_SETTINGS_PROTO_HEAD = '''
|
| -syntax = "proto2";
|
| -
|
| -option optimize_for = LITE_RUNTIME;
|
| -
|
| -package enterprise_management;
|
| -
|
| -// For StringList and PolicyOptions.
|
| -import "cloud_policy.proto";
|
| -
|
| -'''
|
| -
|
| -
|
| -CLOUD_POLICY_PROTO_HEAD = '''
|
| -syntax = "proto2";
|
| -
|
| -option optimize_for = LITE_RUNTIME;
|
| -
|
| -package enterprise_management;
|
| -
|
| -message StringList {
|
| - repeated string entries = 1;
|
| -}
|
| -
|
| -message PolicyOptions {
|
| - enum PolicyMode {
|
| - // The given settings are applied regardless of user choice.
|
| - MANDATORY = 0;
|
| - // The user may choose to override the given settings.
|
| - RECOMMENDED = 1;
|
| - // No policy value is present and the policy should be ignored.
|
| - UNSET = 2;
|
| - }
|
| - optional PolicyMode mode = 1 [default = MANDATORY];
|
| -}
|
| -
|
| -message BooleanPolicyProto {
|
| - optional PolicyOptions policy_options = 1;
|
| - optional bool value = 2;
|
| -}
|
| -
|
| -message IntegerPolicyProto {
|
| - optional PolicyOptions policy_options = 1;
|
| - optional int64 value = 2;
|
| -}
|
| -
|
| -message StringPolicyProto {
|
| - optional PolicyOptions policy_options = 1;
|
| - optional string value = 2;
|
| -}
|
| -
|
| -message StringListPolicyProto {
|
| - optional PolicyOptions policy_options = 1;
|
| - optional StringList value = 2;
|
| -}
|
| -
|
| -'''
|
| -
|
| -
|
| -# Field IDs [1..RESERVED_IDS] will not be used in the wrapping protobuf.
|
| -RESERVED_IDS = 2
|
| -
|
| -
|
| -def _WritePolicyProto(f, policy, fields):
|
| - _OutputComment(f, policy.caption + '\n\n' + policy.desc)
|
| - if policy.items is not None:
|
| - _OutputComment(f, '\nValid values:')
|
| - for item in policy.items:
|
| - _OutputComment(f, ' %s: %s' % (str(item.value), item.caption))
|
| - if policy.policy_type == 'TYPE_DICTIONARY':
|
| - _OutputComment(f, '\nValue schema:\n%s' %
|
| - json.dumps(policy.schema, sort_keys=True, indent=4,
|
| - separators=(',', ': ')))
|
| - _OutputComment(f, '\nSupported on: %s' % ', '.join(policy.platforms))
|
| - f.write('message %sProto {\n' % policy.name)
|
| - f.write(' optional PolicyOptions policy_options = 1;\n')
|
| - f.write(' optional %s %s = 2;\n' % (policy.protobuf_type, policy.name))
|
| - f.write('}\n\n')
|
| - fields += [ ' optional %sProto %s = %s;\n' %
|
| - (policy.name, policy.name, policy.id + RESERVED_IDS) ]
|
| -
|
| -
|
| -def _WriteChromeSettingsProtobuf(policies, os, f):
|
| - f.write(CHROME_SETTINGS_PROTO_HEAD)
|
| -
|
| - fields = []
|
| - f.write('// PBs for individual settings.\n\n')
|
| - for policy in policies:
|
| - # Note: this protobuf also gets the unsupported policies, since it's an
|
| - # exaustive list of all the supported user policies on any platform.
|
| - if not policy.is_device_only:
|
| - _WritePolicyProto(f, policy, fields)
|
| -
|
| - f.write('// --------------------------------------------------\n'
|
| - '// Big wrapper PB containing the above groups.\n\n'
|
| - 'message ChromeSettingsProto {\n')
|
| - f.write(''.join(fields))
|
| - f.write('}\n\n')
|
| -
|
| -
|
| -def _WriteCloudPolicyProtobuf(policies, os, f):
|
| - f.write(CLOUD_POLICY_PROTO_HEAD)
|
| - f.write('message CloudPolicySettings {\n')
|
| - for policy in policies:
|
| - if policy.is_supported and not policy.is_device_only:
|
| - f.write(' optional %sPolicyProto %s = %s;\n' %
|
| - (policy.policy_protobuf_type, policy.name,
|
| - policy.id + RESERVED_IDS))
|
| - f.write('}\n\n')
|
| -
|
| -
|
| -#------------------ protobuf decoder -------------------------------#
|
| -
|
| -CPP_HEAD = '''
|
| -#include <limits>
|
| -#include <string>
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/callback.h"
|
| -#include "base/json/json_reader.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "base/values.h"
|
| -#include "components/policy/core/common/cloud/cloud_external_data_manager.h"
|
| -#include "components/policy/core/common/external_data_fetcher.h"
|
| -#include "components/policy/core/common/policy_map.h"
|
| -#include "policy/policy_constants.h"
|
| -#include "policy/proto/cloud_policy.pb.h"
|
| -
|
| -using google::protobuf::RepeatedPtrField;
|
| -
|
| -namespace policy {
|
| -
|
| -namespace em = enterprise_management;
|
| -
|
| -base::Value* DecodeIntegerValue(google::protobuf::int64 value) {
|
| - if (value < std::numeric_limits<int>::min() ||
|
| - value > std::numeric_limits<int>::max()) {
|
| - LOG(WARNING) << "Integer value " << value
|
| - << " out of numeric limits, ignoring.";
|
| - return NULL;
|
| - }
|
| -
|
| - return base::Value::CreateIntegerValue(static_cast<int>(value));
|
| -}
|
| -
|
| -base::ListValue* DecodeStringList(const em::StringList& string_list) {
|
| - base::ListValue* list_value = new base::ListValue;
|
| - RepeatedPtrField<std::string>::const_iterator entry;
|
| - for (entry = string_list.entries().begin();
|
| - entry != string_list.entries().end(); ++entry) {
|
| - list_value->Append(base::Value::CreateStringValue(*entry));
|
| - }
|
| - return list_value;
|
| -}
|
| -
|
| -base::Value* DecodeJson(const std::string& json) {
|
| - scoped_ptr<base::Value> root(
|
| - base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS));
|
| -
|
| - if (!root)
|
| - LOG(WARNING) << "Invalid JSON string, ignoring: " << json;
|
| -
|
| - // Accept any Value type that parsed as JSON, and leave it to the handler to
|
| - // convert and check the concrete type.
|
| - return root.release();
|
| -}
|
| -
|
| -void DecodePolicy(const em::CloudPolicySettings& policy,
|
| - base::WeakPtr<CloudExternalDataManager> external_data_manager,
|
| - PolicyMap* map) {
|
| -'''
|
| -
|
| -
|
| -CPP_FOOT = '''}
|
| -
|
| -} // namespace policy
|
| -'''
|
| -
|
| -
|
| -def _CreateValue(type, arg):
|
| - if type == 'TYPE_BOOLEAN':
|
| - return 'base::Value::CreateBooleanValue(%s)' % arg
|
| - elif type == 'TYPE_INTEGER':
|
| - return 'DecodeIntegerValue(%s)' % arg
|
| - elif type == 'TYPE_STRING':
|
| - return 'base::Value::CreateStringValue(%s)' % arg
|
| - elif type == 'TYPE_LIST':
|
| - return 'DecodeStringList(%s)' % arg
|
| - elif type == 'TYPE_DICTIONARY' or type == 'TYPE_EXTERNAL':
|
| - return 'DecodeJson(%s)' % arg
|
| - else:
|
| - raise NotImplementedError('Unknown type %s' % type)
|
| -
|
| -
|
| -def _CreateExternalDataFetcher(type, name):
|
| - if type == 'TYPE_EXTERNAL':
|
| - return 'new ExternalDataFetcher(external_data_manager, key::k%s)' % name
|
| - return 'NULL'
|
| -
|
| -
|
| -def _WritePolicyCode(f, policy):
|
| - membername = policy.name.lower()
|
| - proto_type = '%sPolicyProto' % policy.policy_protobuf_type
|
| - f.write(' if (policy.has_%s()) {\n' % membername)
|
| - f.write(' const em::%s& policy_proto = policy.%s();\n' %
|
| - (proto_type, membername))
|
| - f.write(' if (policy_proto.has_value()) {\n')
|
| - f.write(' PolicyLevel level = POLICY_LEVEL_MANDATORY;\n'
|
| - ' bool do_set = true;\n'
|
| - ' if (policy_proto.has_policy_options()) {\n'
|
| - ' do_set = false;\n'
|
| - ' switch(policy_proto.policy_options().mode()) {\n'
|
| - ' case em::PolicyOptions::MANDATORY:\n'
|
| - ' do_set = true;\n'
|
| - ' level = POLICY_LEVEL_MANDATORY;\n'
|
| - ' break;\n'
|
| - ' case em::PolicyOptions::RECOMMENDED:\n'
|
| - ' do_set = true;\n'
|
| - ' level = POLICY_LEVEL_RECOMMENDED;\n'
|
| - ' break;\n'
|
| - ' case em::PolicyOptions::UNSET:\n'
|
| - ' break;\n'
|
| - ' }\n'
|
| - ' }\n'
|
| - ' if (do_set) {\n')
|
| - f.write(' base::Value* value = %s;\n' %
|
| - (_CreateValue(policy.policy_type, 'policy_proto.value()')))
|
| - # TODO(bartfab): |value| == NULL indicates that the policy value could not be
|
| - # parsed successfully. Surface such errors in the UI.
|
| - f.write(' if (value) {\n')
|
| - f.write(' ExternalDataFetcher* external_data_fetcher = %s;\n' %
|
| - _CreateExternalDataFetcher(policy.policy_type, policy.name))
|
| - f.write(' map->Set(key::k%s, level, POLICY_SCOPE_USER,\n' %
|
| - policy.name)
|
| - f.write(' value, external_data_fetcher);\n'
|
| - ' }\n'
|
| - ' }\n'
|
| - ' }\n'
|
| - ' }\n')
|
| -
|
| -
|
| -def _WriteCloudPolicyDecoder(policies, os, f):
|
| - f.write(CPP_HEAD)
|
| - for policy in policies:
|
| - if policy.is_supported and not policy.is_device_only:
|
| - _WritePolicyCode(f, policy)
|
| - f.write(CPP_FOOT)
|
| -
|
| -
|
| -if __name__ == '__main__':
|
| - sys.exit(main())
|
|
|