blob: 2fe69ff98d183c36bffc745c5b2778471c3d8447 [file] [log] [blame]
# Copyright 2019 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from autotest_lib.client.common_lib import error
class Policy(object):
"""
Class structure for a single policy object.
A policy has the following attributes:
value
source
level
scope
name
All of the attributes are protected in @setter's. To set a value simply
create a policy object (e.g. "somePolicy = Policy()") and set the desired
value (somePolicy.value=True).
This class will be used by the policy_manager for configuring and checking
policies for Enterprise tests.
"""
def __init__(self):
self._value = None
self._source = None
self._scope = None
self._level = None
self._name = None
def is_formatted_value(self, data):
"""
Checks if the received value is a a dict containing all policy stats.
"""
if not isinstance(data, dict):
return False
received_keys = set(['scope', 'source', 'level', 'value'])
return received_keys == set(data.keys())
def get_policy_as_dict(self):
"""
Returns the policy as a dict, in the same format as in the
chrome://policy json file.
"""
return {self.name: {'scope': self._scope,
'source': self._source,
'level': self._level,
'value': self._value}}
def set_policy_from_dict(self, data):
"""
Sets the policy attributes from a provided dict matching the following
format:
{"scope": scopeValue, "source": sourceValue, "level": levelValue,
"value": value}
@param data: a dict representing the policy values, as specified above.
"""
if not self.is_formatted_value(data):
raise error.TestError("""Incorrect input data provided. Value
provided must be dict with the keys: "scope", "source", "level",
"value". Got {}""".format(data))
self.scope = data['scope']
self.source = data['source']
self.level = data['level']
self.value = data['value']
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value
@property
def name(self):
return self._name
@name.setter
def name(self, name):
self._name = name
@property
def level(self):
return self._level
@level.setter
def level(self, level):
self._level = level
@property
def scope(self):
return self._scope
@scope.setter
def scope(self, scope):
self._scope = scope
@property
def source(self):
return self._source
@source.setter
def source(self, source):
self._source = source
@property
def group(self):
return None
@group.setter
def group(self, group):
"""
If setting a policy, you can also set it from a group ("user",
"suggested_user", "device"). Doing this will automatically set the other
policy attributes.
If the group is None, nothing will be set.
@param group: None or value of the policy group.
"""
if not group:
return
self._source = 'cloud'
if group != 'suggested_user':
self._level = 'mandatory'
else:
self._level = 'recommended'
if group == 'device':
self._scope = 'machine'
else:
self._scope = 'user'
def __ne__(self, other):
return not self.__eq__(other)
def __eq__(self, other):
"""
Override of the "==" statment. Verify one policy object verse another.
Will return True if the policy value, source, scope, and level are
equal, otherwise False.
There is a special check for the Network Policy, due to a displayed
policy having visual obfuscation (********).
"""
if self.value != other.value:
if is_network_policy(other.name):
return check_obfuscation(other.value)
else:
logging.info('value configured {} != received {}'
.format(self.value, other.value))
return False
if self.source != other.source:
logging.info('source configured {} != received {}'
.format(self.source, other.source))
return False
if self.scope != other.scope:
logging.info('scope configured {} != received {}'
.format(self.scope, other.scope))
return False
if self.level != other.level:
logging.info('level configured {} != received {}'
.format(self.level, other.level))
return False
return True
def __repr__(self):
policy_data = self.get_policy_as_dict()
return "<POLICY DATA OBJECT> | {}".format(policy_data)
def is_network_policy(policy_name):
"""
Returns true if the policy name is that of an OpenNetworkConfiguration.
"""
if policy_name.endswith('OpenNetworkConfiguration'):
return True
def check_obfuscation(other_value):
"""Checks if value is a network policy, and is obfuscated."""
DISPLAY_PWORD = '*' * 8
for network in other_value.get('NetworkConfigurations', []):
wifi = network.get('WiFi', {})
if 'Passphrase' in wifi and wifi['Passphrase'] != DISPLAY_PWORD:
return False
if ('EAP' in wifi and
'Password' in wifi['EAP'] and
wifi['EAP']['Password'] != DISPLAY_PWORD):
return False
for cert in other_value.get('Certificates', []):
if 'PKCS12' in cert:
if cert['PKCS12'] != DISPLAY_PWORD:
return False
return True