OLD | NEW |
---|---|
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 ''' | 6 ''' |
7 Checks a policy_templates.json file for conformity to its syntax specification. | 7 Checks a policy_templates.json file for conformity to its syntax specification. |
8 ''' | 8 ''' |
9 | 9 |
10 import json | 10 import json |
(...skipping 12 matching lines...) Expand all Loading... | |
23 TYPE_TO_SCHEMA = { | 23 TYPE_TO_SCHEMA = { |
24 'int': 'integer', | 24 'int': 'integer', |
25 'list': 'array', | 25 'list': 'array', |
26 'dict': 'object', | 26 'dict': 'object', |
27 'main': 'boolean', | 27 'main': 'boolean', |
28 'string': 'string', | 28 'string': 'string', |
29 'int-enum': 'integer', | 29 'int-enum': 'integer', |
30 'string-enum': 'string', | 30 'string-enum': 'string', |
31 } | 31 } |
32 | 32 |
33 # List of boolean policies that have been introduced with negative polarity in | |
34 # the past and should not trigger the negative polarity check. | |
35 LEGACY_INVERTED_POLARITY_WHITELIST = [ | |
36 'DeveloperToolsDisabled', | |
37 'DeviceAutoUpdateDisabled', | |
38 'Disable3DAPIs', | |
39 'DisableAuthNegotiateCnameLookup', | |
40 'DisablePluginFinder', | |
41 'DisablePrintPreview', | |
42 'DisableSafeBrowsingProceedAnyway', | |
43 'DisableScreenshots', | |
44 'DisableSpdy', | |
45 'DisableSSLRecordSplitting', | |
46 'ExternalStorageDisabledforrealz', | |
47 'GDataDisabled', | |
48 'GDataDisabledOverCellular', | |
49 'SavingBrowserHistoryDisabled', | |
50 'SyncDisabled', | |
51 ] | |
52 | |
33 class PolicyTemplateChecker(object): | 53 class PolicyTemplateChecker(object): |
34 | 54 |
35 def __init__(self): | 55 def __init__(self): |
36 self.error_count = 0 | 56 self.error_count = 0 |
37 self.warning_count = 0 | 57 self.warning_count = 0 |
38 self.num_policies = 0 | 58 self.num_policies = 0 |
39 self.num_groups = 0 | 59 self.num_groups = 0 |
40 self.num_policies_in_groups = 0 | 60 self.num_policies_in_groups = 0 |
41 self.options = None | 61 self.options = None |
42 | 62 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
120 ''' | 140 ''' |
121 for i in range(len(policy_ids)): | 141 for i in range(len(policy_ids)): |
122 if (i + 1) not in policy_ids: | 142 if (i + 1) not in policy_ids: |
123 self._Error('No policy with id: %s' % (i + 1)) | 143 self._Error('No policy with id: %s' % (i + 1)) |
124 | 144 |
125 def _CheckPolicySchema(self, policy, policy_type): | 145 def _CheckPolicySchema(self, policy, policy_type): |
126 '''Checks that the 'schema' field matches the 'type' field.''' | 146 '''Checks that the 'schema' field matches the 'type' field.''' |
127 self._CheckContains(policy, 'schema', dict) | 147 self._CheckContains(policy, 'schema', dict) |
128 if isinstance(policy.get('schema'), dict): | 148 if isinstance(policy.get('schema'), dict): |
129 self._CheckContains(policy['schema'], 'type', str) | 149 self._CheckContains(policy['schema'], 'type', str) |
130 if policy['schema'].get('type') != TYPE_TO_SCHEMA[policy_type]: | 150 schema_type = policy['schema'].get('type') |
151 if schema_type != TYPE_TO_SCHEMA[policy_type]: | |
131 self._Error('Schema type must match the existing type for policy %s' % | 152 self._Error('Schema type must match the existing type for policy %s' % |
132 policy.get('name')) | 153 policy.get('name')) |
133 | 154 |
155 # Checks that boolean policies are not negated (which makes them harder to | |
156 # reason about). | |
157 if (schema_type == 'boolean' and | |
158 "disable" in policy.get('name').lower() and | |
Joao da Silva
2012/08/06 21:49:05
Nit: 'disable' with single quotes
Mattias Nissler (ping if slow)
2012/08/07 08:20:07
Done.
| |
159 policy.get('name') not in LEGACY_INVERTED_POLARITY_WHITELIST): | |
160 self._Error(('Boolean policy %s uses negative polarity, please make ' + | |
161 'new boolean policies follow the XYZEnabled pattern. ' + | |
162 'See also http://crbug.com/85687') % policy.get('name')) | |
163 | |
164 | |
134 def _CheckPolicy(self, policy, is_in_group, policy_ids): | 165 def _CheckPolicy(self, policy, is_in_group, policy_ids): |
135 if not isinstance(policy, dict): | 166 if not isinstance(policy, dict): |
136 self._Error('Each policy must be a dictionary.', 'policy', None, policy) | 167 self._Error('Each policy must be a dictionary.', 'policy', None, policy) |
137 return | 168 return |
138 | 169 |
139 # There should not be any unknown keys in |policy|. | 170 # There should not be any unknown keys in |policy|. |
140 for key in policy: | 171 for key in policy: |
141 if key not in ('name', 'type', 'caption', 'desc', 'device_only', | 172 if key not in ('name', 'type', 'caption', 'desc', 'device_only', |
142 'supported_on', 'label', 'policies', 'items', | 173 'supported_on', 'label', 'policies', 'items', |
143 'example_value', 'features', 'deprecated', 'future', | 174 'example_value', 'features', 'deprecated', 'future', |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 if filename is None: | 465 if filename is None: |
435 if len(args) != 2: | 466 if len(args) != 2: |
436 parser.print_help() | 467 parser.print_help() |
437 sys.exit(1) | 468 sys.exit(1) |
438 filename = args[1] | 469 filename = args[1] |
439 return self.Main(filename, options) | 470 return self.Main(filename, options) |
440 | 471 |
441 | 472 |
442 if __name__ == '__main__': | 473 if __name__ == '__main__': |
443 sys.exit(PolicyTemplateChecker().Run(sys.argv)) | 474 sys.exit(PolicyTemplateChecker().Run(sys.argv)) |
OLD | NEW |