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

Side by Side Diff: components/policy/tools/generate_policy_source.py

Issue 846413003: Revert "Expose chrome policies using Android's App Restrictions Schema" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2272
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/policy/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 '''python %prog [options] platform chromium_os_flag template 6 '''python %prog [options] platform chromium_os_flag template
7 7
8 platform specifies which platform source is being generated for 8 platform specifies which platform source is being generated for
9 and can be one of (win, mac, linux) 9 and can be one of (win, mac, linux)
10 chromium_os_flag should be 1 if this is a Chromium OS build 10 chromium_os_flag should be 1 if this is a Chromium OS build
11 template is the path to a .json policy template file.''' 11 template is the path to a .json policy template file.'''
12 12
13 from __future__ import with_statement 13 from __future__ import with_statement
14 from functools import partial 14 from functools import partial
15 import json 15 import json
16 from optparse import OptionParser 16 from optparse import OptionParser
17 import re 17 import re
18 import sys 18 import sys
19 import textwrap 19 import textwrap
20 import types 20 import types
21 from xml.sax.saxutils import escape as xml_escape
22 21
23 22
24 CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome' 23 CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome'
25 CHROMIUM_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Chromium' 24 CHROMIUM_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Chromium'
26 25
27 26
28 class PolicyDetails: 27 class PolicyDetails:
29 """Parses a policy template and caches all its details.""" 28 """Parses a policy template and caches all its details."""
30 29
31 # Maps policy types to a tuple with 5 other types: 30 # Maps policy types to a tuple with 3 other types:
32 # - the equivalent base::Value::Type or 'TYPE_EXTERNAL' if the policy 31 # - the equivalent base::Value::Type or 'TYPE_EXTERNAL' if the policy
33 # references external data 32 # references external data
34 # - the equivalent Protobuf field type 33 # - the equivalent Protobuf field type
35 # - the name of one of the protobufs for shared policy types 34 # - the name of one of the protobufs for shared policy types
36 # - the equivalent type in Android's App Restriction Schema
37 # - whether the equivalent app restriction type needs supporting resources
38 # TODO(joaodasilva): refactor the 'dict' type into a more generic 'json' type 35 # TODO(joaodasilva): refactor the 'dict' type into a more generic 'json' type
39 # that can also be used to represent lists of other JSON objects. 36 # that can also be used to represent lists of other JSON objects.
40 TYPE_MAP = { 37 TYPE_MAP = {
41 'dict': ('TYPE_DICTIONARY', 'string', 'String', 38 'dict': ('TYPE_DICTIONARY', 'string', 'String'),
42 'string', False), 39 'external': ('TYPE_EXTERNAL', 'string', 'String'),
43 'external': ('TYPE_EXTERNAL', 'string', 'String', 40 'int': ('TYPE_INTEGER', 'int64', 'Integer'),
44 'invalid', False), 41 'int-enum': ('TYPE_INTEGER', 'int64', 'Integer'),
45 'int': ('TYPE_INTEGER', 'int64', 'Integer', 42 'list': ('TYPE_LIST', 'StringList', 'StringList'),
46 'integer', False), 43 'main': ('TYPE_BOOLEAN', 'bool', 'Boolean'),
47 'int-enum': ('TYPE_INTEGER', 'int64', 'Integer', 44 'string': ('TYPE_STRING', 'string', 'String'),
48 'choice', True), 45 'string-enum': ('TYPE_STRING', 'string', 'String'),
49 'list': ('TYPE_LIST', 'StringList', 'StringList', 46 'string-enum-list': ('TYPE_LIST', 'StringList', 'StringList'),
50 'string', False),
51 'main': ('TYPE_BOOLEAN', 'bool', 'Boolean',
52 'bool', False),
53 'string': ('TYPE_STRING', 'string', 'String',
54 'string', False),
55 'string-enum': ('TYPE_STRING', 'string', 'String',
56 'choice', True),
57 'string-enum-list': ('TYPE_LIST', 'StringList', 'StringList',
58 'multi-select', True),
59 } 47 }
60 48
61 class EnumItem: 49 class EnumItem:
62 def __init__(self, item): 50 def __init__(self, item):
63 self.caption = PolicyDetails._RemovePlaceholders(item['caption']) 51 self.caption = PolicyDetails._RemovePlaceholders(item['caption'])
64 self.value = item['value'] 52 self.value = item['value']
65 53
66 def __init__(self, policy, os, is_chromium_os): 54 def __init__(self, policy, os, is_chromium_os):
67 self.id = policy['id'] 55 self.id = policy['id']
68 self.name = policy['name'] 56 self.name = policy['name']
(...skipping 21 matching lines...) Expand all
90 self.platforms.append(platform_sub) 78 self.platforms.append(platform_sub)
91 else: 79 else:
92 self.platforms.append(platform) 80 self.platforms.append(platform)
93 81
94 self.platforms.sort() 82 self.platforms.sort()
95 self.is_supported = expected_platform in self.platforms 83 self.is_supported = expected_platform in self.platforms
96 84
97 if not PolicyDetails.TYPE_MAP.has_key(policy['type']): 85 if not PolicyDetails.TYPE_MAP.has_key(policy['type']):
98 raise NotImplementedError('Unknown policy type for %s: %s' % 86 raise NotImplementedError('Unknown policy type for %s: %s' %
99 (policy['name'], policy['type'])) 87 (policy['name'], policy['type']))
100 self.policy_type, self.protobuf_type, self.policy_protobuf_type, \ 88 self.policy_type, self.protobuf_type, self.policy_protobuf_type = \
101 self.restriction_type, self.has_restriction_resources = \ 89 PolicyDetails.TYPE_MAP[policy['type']]
102 PolicyDetails.TYPE_MAP[policy['type']]
103 self.schema = policy['schema'] 90 self.schema = policy['schema']
104 91
105 self.desc = '\n'.join( 92 self.desc = '\n'.join(
106 map(str.strip, 93 map(str.strip,
107 PolicyDetails._RemovePlaceholders(policy['desc']).splitlines())) 94 PolicyDetails._RemovePlaceholders(policy['desc']).splitlines()))
108 self.caption = PolicyDetails._RemovePlaceholders(policy['caption']) 95 self.caption = PolicyDetails._RemovePlaceholders(policy['caption'])
109 self.max_size = policy.get('max_size', 0) 96 self.max_size = policy.get('max_size', 0)
110 97
111 items = policy.get('items') 98 items = policy.get('items')
112 if items is None: 99 if items is None:
(...skipping 29 matching lines...) Expand all
142 help='generate cloud policy protobuf file', 129 help='generate cloud policy protobuf file',
143 metavar='FILE') 130 metavar='FILE')
144 parser.add_option('--csp', '--chrome-settings-protobuf', 131 parser.add_option('--csp', '--chrome-settings-protobuf',
145 dest='chrome_settings_proto_path', 132 dest='chrome_settings_proto_path',
146 help='generate chrome settings protobuf file', 133 help='generate chrome settings protobuf file',
147 metavar='FILE') 134 metavar='FILE')
148 parser.add_option('--cpd', '--cloud-policy-decoder', 135 parser.add_option('--cpd', '--cloud-policy-decoder',
149 dest='cloud_policy_decoder_path', 136 dest='cloud_policy_decoder_path',
150 help='generate C++ code decoding the cloud policy protobuf', 137 help='generate C++ code decoding the cloud policy protobuf',
151 metavar='FILE') 138 metavar='FILE')
152 parser.add_option('--ard', '--app-restrictions-definition',
153 dest='app_restrictions_path',
154 help='generate an XML file as specified by '
155 'Android\'s App Restriction Schema',
156 metavar='FILE')
157 parser.add_option('--arr', '--app-restrictions-resources',
158 dest='app_resources_path',
159 help='generate an XML file with resources supporting the '
160 'restrictions defined in --app-restrictions-definition '
161 'parameter',
162 metavar='FILE')
163 139
164 (opts, args) = parser.parse_args() 140 (opts, args) = parser.parse_args()
165 141
166 if len(args) != 3: 142 if len(args) != 3:
167 print 'exactly platform, chromium_os flag and input file must be specified.' 143 print 'exactly platform, chromium_os flag and input file must be specified.'
168 parser.print_help() 144 parser.print_help()
169 return 2 145 return 2
170 146
171 os = args[0] 147 os = args[0]
172 is_chromium_os = args[1] == '1' 148 is_chromium_os = args[1] == '1'
173 template_file_name = args[2] 149 template_file_name = args[2]
174 150
175 template_file_contents = _LoadJSONFile(template_file_name) 151 template_file_contents = _LoadJSONFile(template_file_name)
176 policy_details = [ PolicyDetails(policy, os, is_chromium_os) 152 policy_details = [ PolicyDetails(policy, os, is_chromium_os)
177 for policy in _Flatten(template_file_contents) ] 153 for policy in _Flatten(template_file_contents) ]
178 sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name) 154 sorted_policy_details = sorted(policy_details, key=lambda policy: policy.name)
179 155
180 def GenerateFile(path, writer, sorted=False, xml=False): 156 def GenerateFile(path, writer, sorted=False):
181 if path: 157 if path:
182 with open(path, 'w') as f: 158 with open(path, 'w') as f:
183 _OutputGeneratedWarningHeader(f, template_file_name, xml) 159 _OutputGeneratedWarningHeader(f, template_file_name)
184 writer(sorted and sorted_policy_details or policy_details, os, f) 160 writer(sorted and sorted_policy_details or policy_details, os, f)
185 161
186 GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True) 162 GenerateFile(opts.header_path, _WritePolicyConstantHeader, sorted=True)
187 GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True) 163 GenerateFile(opts.source_path, _WritePolicyConstantSource, sorted=True)
188 GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf) 164 GenerateFile(opts.cloud_policy_proto_path, _WriteCloudPolicyProtobuf)
189 GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf) 165 GenerateFile(opts.chrome_settings_proto_path, _WriteChromeSettingsProtobuf)
190 GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder) 166 GenerateFile(opts.cloud_policy_decoder_path, _WriteCloudPolicyDecoder)
191 167
192 if os == 'android':
193 GenerateFile(opts.app_restrictions_path, _WriteAppRestrictions, xml=True)
194 GenerateFile(opts.app_resources_path, _WriteResourcesForPolicies, xml=True)
195
196 return 0 168 return 0
197 169
198 170
199 #------------------ shared helpers ---------------------------------# 171 #------------------ shared helpers ---------------------------------#
200 172
201 def _OutputGeneratedWarningHeader(f, template_file_path, xml_style): 173 def _OutputGeneratedWarningHeader(f, template_file_path):
202 left_margin = '//' 174 f.write('//\n'
203 if xml_style: 175 '// DO NOT MODIFY THIS FILE DIRECTLY!\n'
204 left_margin = ' ' 176 '// IT IS GENERATED BY generate_policy_source.py\n'
205 f.write('<?xml version="1.0" encoding="utf-8"?>\n' 177 '// FROM ' + template_file_path + '\n'
206 '<!--\n') 178 '//\n\n')
207 else:
208 f.write('//\n')
209
210 f.write(left_margin + ' DO NOT MODIFY THIS FILE DIRECTLY!\n')
211 f.write(left_margin + ' IT IS GENERATED BY generate_policy_source.py\n')
212 f.write(left_margin + ' FROM ' + template_file_path + '\n')
213
214 if xml_style:
215 f.write('-->\n\n')
216 else:
217 f.write(left_margin + '\n\n')
218 179
219 180
220 COMMENT_WRAPPER = textwrap.TextWrapper() 181 COMMENT_WRAPPER = textwrap.TextWrapper()
221 COMMENT_WRAPPER.width = 80 182 COMMENT_WRAPPER.width = 80
222 COMMENT_WRAPPER.initial_indent = '// ' 183 COMMENT_WRAPPER.initial_indent = '// '
223 COMMENT_WRAPPER.subsequent_indent = '// ' 184 COMMENT_WRAPPER.subsequent_indent = '// '
224 COMMENT_WRAPPER.replace_whitespace = False 185 COMMENT_WRAPPER.replace_whitespace = False
225 186
226 187
227 # Writes a comment, each line prefixed by // and wrapped to 80 spaces. 188 # Writes a comment, each line prefixed by // and wrapped to 80 spaces.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 f.write('};\n\n') 554 f.write('};\n\n')
594 555
595 def GetByID(self, id_str): 556 def GetByID(self, id_str):
596 if not isinstance(id_str, types.StringTypes): 557 if not isinstance(id_str, types.StringTypes):
597 return id_str 558 return id_str
598 if not self.id_map.has_key(id_str): 559 if not self.id_map.has_key(id_str):
599 raise RuntimeError('Invalid $ref: ' + id_str) 560 raise RuntimeError('Invalid $ref: ' + id_str)
600 return self.id_map[id_str] 561 return self.id_map[id_str]
601 562
602 def ResolveID(self, index, params): 563 def ResolveID(self, index, params):
603 return params[:index] + (self.GetByID(params[index]),) + params[index + 1:] 564 return params[:index] + (self.GetByID(params[index]),) + params[index+1:]
604 565
605 def ResolveReferences(self): 566 def ResolveReferences(self):
606 """Resolve reference mapping, required to be called after Generate() 567 """Resolve reference mapping, required to be called after Generate()
607 568
608 After calling Generate(), the type of indices used in schema structures 569 After calling Generate(), the type of indices used in schema structures
609 might be either int or string. An int type suggests that it's a resolved 570 might be either int or string. An int type suggests that it's a resolved
610 index, but for string type it's unresolved. Resolving a reference is as 571 index, but for string type it's unresolved. Resolving a reference is as
611 simple as looking up for corresponding ID in self.id_map, and replace the 572 simple as looking up for corresponding ID in self.id_map, and replace the
612 old index with the mapped index. 573 old index with the mapped index.
613 """ 574 """
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 961
1001 962
1002 def _WriteCloudPolicyDecoder(policies, os, f): 963 def _WriteCloudPolicyDecoder(policies, os, f):
1003 f.write(CPP_HEAD) 964 f.write(CPP_HEAD)
1004 for policy in policies: 965 for policy in policies:
1005 if policy.is_supported and not policy.is_device_only: 966 if policy.is_supported and not policy.is_device_only:
1006 _WritePolicyCode(f, policy) 967 _WritePolicyCode(f, policy)
1007 f.write(CPP_FOOT) 968 f.write(CPP_FOOT)
1008 969
1009 970
1010 def _EscapeResourceString(raw_resource):
1011 if type(raw_resource) == int:
1012 return raw_resource
1013 return xml_escape(raw_resource)\
1014 .replace('\\', '\\\\')\
1015 .replace('\"','\\\"')\
1016 .replace('\'','\\\'')
1017
1018 def _WriteAppRestrictions(policies, os, f):
1019
1020 def WriteRestrictionCommon(key):
1021 f.write(' <restriction\n'
1022 ' android:key="%s"\n' % key)
1023 f.write(' android:title="@string/%sTitle"\n' % key)
1024 f.write(' android:description="@string/%sDesc"\n' % key)
1025
1026 def WriteItemsDefinition(key):
1027 f.write(' android:entries="@array/%sEntries"\n' % key)
1028 f.write(' android:entryValues="@array/%sValues"\n' % key)
1029
1030 def WriteAppRestriction(policy):
1031 policy_name = policy.name
1032 WriteRestrictionCommon(policy_name)
1033
1034 if policy.has_restriction_resources:
1035 WriteItemsDefinition(policy_name)
1036
1037 f.write(' android:restrictionType="%s"/>' % policy.restriction_type)
1038 f.write('\n\n')
1039
1040 # _WriteAppRestrictions body
1041 f.write('<restrictions xmlns:android="'
1042 'http://schemas.android.com/apk/res/android">\n\n')
1043 for policy in policies:
1044 if policy.is_supported and policy.restriction_type != 'invalid':
1045 WriteAppRestriction(policy)
1046 f.write('</restrictions>')
1047
1048
1049 def _WriteResourcesForPolicies(policies, os, f):
1050
1051 # TODO(knn): Update this to support i18n.
1052 def WriteString(key, value):
1053 f.write(' <string name="%s">%s</string>\n'
1054 % (key, _EscapeResourceString(value)))
1055
1056 def WriteItems(key, items):
1057 if items:
1058 f.write(' <string-array name="%sEntries">\n' % key)
1059 for item in items:
1060 f.write(' <item>%s</item>\n' %
1061 _EscapeResourceString(item.caption))
1062 f.write(' </string-array>\n')
1063 f.write(' <string-array name="%sValues">\n' % key)
1064 for item in items:
1065 f.write(' <item>%s</item>\n' % _EscapeResourceString(item.value))
1066 f.write(' </string-array>\n')
1067
1068 def WriteResourceForPolicy(policy):
1069 policy_name = policy.name
1070 WriteString(policy_name + 'Title', policy.caption)
1071
1072 # Get the first line of the policy description.
1073 description = policy.desc.split('\n', 1)[0]
1074 WriteString(policy_name + 'Desc', description)
1075
1076 if policy.has_restriction_resources:
1077 WriteItems(policy_name, policy.items)
1078
1079 # _WriteResourcesForPolicies body
1080 f.write('<resources>\n\n')
1081 for policy in policies:
1082 if policy.is_supported and policy.restriction_type != 'invalid':
1083 WriteResourceForPolicy(policy)
1084 f.write('</resources>')
1085
1086
1087 if __name__ == '__main__': 971 if __name__ == '__main__':
1088 sys.exit(main()) 972 sys.exit(main())
OLDNEW
« no previous file with comments | « components/policy/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698