1# Copyright 2019 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4""" 5 6Helper file for handling policy fetching/parsing/formatting. This file has 7working unitests located in ${THIS_FILE_NAME}_unittest.py. If you modify this 8file, add/fix/adjust the unittests for proper code coverage and 9re-run. 10 11Read instructions in the unittest file on how to run. 12 13""" 14import json 15import time 16 17import six 18 19from autotest_lib.client.common_lib import error 20 21# Default settings for managed user policies 22 23 24def get_all_policies(autotest_ext): 25 """Returns a dict of all the policies on the device.""" 26 27 policy_data = _get_pol_from_api(autotest_ext) 28 if not policy_data: 29 raise error.TestError('API did not return policy data!') 30 _reformat_policies(policy_data) 31 32 return policy_data 33 34 35def _get_pol_from_api(autotest_ext): 36 """Call the getAllPolicies API, return raw result, clear stored data.""" 37 new_promise = '''new Promise(function(resolve, reject) { 38 chrome.autotestPrivate.getAllEnterprisePolicies(function(policies) { 39 if (chrome.runtime.lastError) { 40 reject(new Error(chrome.runtime.lastError.message)); 41 } else { 42 resolve(policies); 43 } 44 }) 45 })''' 46 policy_data = autotest_ext.EvaluateJavaScript(new_promise, promise=True) 47 return policy_data 48 49 50def _wait_for_new_pols_after_refresh(autotest_ext): 51 """ 52 Wait up to 1 second for the polices to update when refreshing. 53 54 Note: This is non-breaking, thus even if the policies do not update, once 55 the timeout expires, the function will exit. 56 57 """ 58 prior = _get_pol_from_api(autotest_ext) 59 _call_refresh_policies_from_api(autotest_ext) 60 t1 = time.time() 61 while time.time() - t1 < 1: 62 curr = _get_pol_from_api(autotest_ext) 63 if curr != prior: 64 break 65 66 67def _call_refresh_policies_from_api(autotest_ext): 68 """Call the refreshEnterprisePolicies from autotestPrivate.""" 69 new_promise = '''new Promise(function(resolve, reject) { 70 chrome.autotestPrivate.refreshEnterprisePolicies(function() { 71 if (chrome.runtime.lastError) { 72 reject(new Error(chrome.runtime.lastError.message)); 73 } else { 74 resolve(); 75 } 76 }) 77 })''' 78 autotest_ext.EvaluateJavaScript(new_promise, promise=True) 79 80 81def refresh_policies(autotest_ext, wait_for_new=False): 82 """Force a policy fetch.""" 83 84 if wait_for_new: 85 _wait_for_new_pols_after_refresh(autotest_ext) 86 else: 87 _call_refresh_policies_from_api(autotest_ext) 88 89 90def _reformat_policies(policy_dict): 91 """ 92 Reformat visually formatted dicts to type dict (and not unicode). 93 94 Given a dict, check if 'value' is a key in the value field. If so, check 95 if the data of ['value'] is unicode. If it is, attempt to load it as json. 96 If not, but the value field is a dict, recursively call this function to 97 check again. 98 99 @param: policy_dict, a policy dictionary. 100 101 """ 102 for k, v in policy_dict.items(): 103 if not v: 104 # No data 105 continue 106 if 'value' in v: 107 if type(v['value']) == six.text_type: 108 _remove_visual_formatting(v) 109 elif isinstance(v, dict): 110 _reformat_policies(v) 111 112 113def _remove_visual_formatting(policy_value): 114 """ 115 Attempt to remove any visual formatting. 116 117 Note: policy_value can be either unicode dict or string. If json.loads() 118 raises a ValueError, it is a string, and we do not need to format. 119 120 """ 121 try: 122 policy_value['value'] = json.loads(policy_value['value']) 123 except ValueError: 124 return 125