1#!/usr/bin/env python 2# Copyright (c) 2014 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6 7import base64 8 9from xml.dom import minidom 10from grit.format.policy_templates.writers import plist_writer 11 12 13# This writer outputs a Property List with an example for each of the policies 14# supported on iOS. This plist can be pushed to Chrome on iOS via the MDM API 15# introduced in iOS 7. 16 17CHROME_POLICY_COMMENT = '''\ 18 ChromePolicy is the preferred key to configure Chrome. 19 Each of the keys in this <dict> configures a Chrome policy. 20 All of the Chrome policies are configured with an example 21 value below. 22 Note that it's not necessary to configure all of them. ''' 23 24ENCODED_CHROME_POLICY_COMMENT = '''\ 25 EncodedChromePolicy contains a Property List file, encoded in Base64, 26 which contains the same policies that can go in ChromePolicy. 27 This key can be used by vendors that restrict the app configuration 28 types to strings. 29 The value of this string can be validated by running these 30 commands in Mac OS X: 31 32 # (first, copy-paste the string into a file named "policy.plist") 33 # base64 -D < policy.plist > decoded_policy.plist 34 # plutil -lint decoded_policy.plist 35 36 plutil should indicate that decoded_policy.plist is valid, 37 otherwise Chrome will reject the encoded string too. 38 39 This command can be used to pretty-print the plist file: 40 41 # plutil -convert xml1 decoded_policy.plist 42 43 Note that <ChromePolicy> is the preferred key to configure Chrome. 44 If <ChromePolicy> is present then <EncodedChromePolicy> is ignored. ''' 45 46def GetWriter(config): 47 '''Factory method for creating IOSPlistWriter objects. 48 See the constructor of TemplateWriter for description of 49 arguments. 50 ''' 51 return IOSPlistWriter(['ios'], config) 52 53 54class IOSPlistWriter(plist_writer.PListWriter): 55 '''Class for generating policy templates in the iOS plist format. 56 It is used by PolicyTemplateGenerator to write plist files. 57 ''' 58 59 # Overridden. 60 def IsPolicySupported(self, policy): 61 # Output examples only for policies that are supported on iOS. 62 for support_on in policy['supported_on']: 63 if ('ios' in support_on['platforms'] and 64 support_on['until_version'] == '' and 65 super(IOSPlistWriter, self).IsPolicySupported(policy)): 66 return True 67 return False 68 69 def _WriteValue(self, parent, value): 70 if type(value) == bool: 71 self.AddElement(parent, 'true' if value else 'false') 72 elif type(value) == int: 73 self.AddElement(parent, 'integer', {}, str(value)) 74 elif type(value) == str: 75 self.AddElement(parent, 'string', {}, value) 76 elif type(value) == list: 77 array = self.AddElement(parent, 'array') 78 for element in value: 79 self._WriteValue(array, element) 80 elif type(value) == dict: 81 dic = self.AddElement(parent, 'dict') 82 for k, v in sorted(value.iteritems()): 83 self.AddElement(dic, 'key', {}, k) 84 self._WriteValue(dic, v) 85 else: 86 raise ValueError('Unsupported type in example value: ' + type(value)) 87 88 # Overridden. 89 def WritePolicy(self, policy): 90 for dict in [self._dict, self._encoded_dict]: 91 self.AddElement(dict, 'key', {}, policy['name']) 92 self._WriteValue(dict, policy['example_value']) 93 94 # Overridden. 95 # |self._plist| is created in super.Init(). 96 def BeginTemplate(self): 97 self._plist.attributes['version'] = '1.0' 98 self._root_dict = self.AddElement(self._plist, 'dict') 99 self.AddComment(self._root_dict, CHROME_POLICY_COMMENT) 100 self._dict = self._AddKeyValuePair(self._root_dict, 'ChromePolicy', 'dict') 101 102 self._encoded_plist.attributes['version'] = '1.0' 103 self._encoded_dict = self.AddElement(self._encoded_plist, 'dict') 104 105 # Overridden. 106 def EndTemplate(self): 107 # Add the "EncodedChromePolicy" entry. 108 encoded = base64.b64encode(self._encoded_doc.toxml()) 109 self.AddComment(self._root_dict, ENCODED_CHROME_POLICY_COMMENT) 110 self._AddStringKeyValuePair(self._root_dict, 'EncodedChromePolicy', encoded) 111 112 # Overridden. 113 def Init(self): 114 super(IOSPlistWriter, self).Init() 115 # Create a secondary DOM for the EncodedChromePolicy Plist, which will be 116 # serialized and encoded in EndTemplate. 117 self._encoded_doc = self.CreatePlistDocument() 118 self._encoded_plist = self._encoded_doc.documentElement 119 120 # Overridden. 121 def GetTemplateText(self): 122 return self.ToPrettyXml(self._doc, encoding='UTF-8') 123