xref: /aosp_15_r20/external/autotest/client/cros/enterprise/enterprise_policy_utils.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
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