blob: 7a76c89bff900ab9da88c7b935b8327fc01bcf6d [file] [log] [blame]
# Copyright 2015 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.cros import httpd
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import enterprise_policy_base
POLICY_NAME = 'URLWhitelist'
URL_HOST = 'http://localhost'
URL_PORT = 8080
URL_BASE = '%s:%d/%s' % (URL_HOST, URL_PORT, 'test_data')
BLOCKED_URLS_LIST = [URL_BASE + website for website in
['/website1.html',
'/website2.html',
'/website3.html']]
SINGLE_WHITELISTED_FILE_DATA = BLOCKED_URLS_LIST[:1]
MULTIPLE_WHITELISTED_FILES_DATA = BLOCKED_URLS_LIST[:2]
BLOCKED_USER_MESSAGE = 'Webpage Blocked'
BLOCKED_ERROR_MESSAGE = 'ERR_BLOCKED_BY_ADMINISTRATOR'
SUPPORTING_POLICIES = {'URLBlacklist': BLOCKED_URLS_LIST}
class policy_URLWhitelist(enterprise_policy_base.EnterprisePolicyTest):
"""
Test effect of URLWhitleist policy on Chrome OS behavior.
Navigate to all the websites in the BLOCKED_URLS_LIST. Verify that the
websites specified by the URLWhitelist policy value are not blocked.
Also verify that the websites not in the URLWhitelist policy
value are blocked.
Two TEST_CASES (SingleWhitelistedFile, MultipleWhitelistedFiles) are
designed to verify that the functionality works regardless of whether a
a SINGLE website is specified in the URLWhitelist policy or if MULTIPLE
websites are specified.
The third TEST_CASE (NotSet) is designed to verify that all of the websites
are blocked since the URLWhitelistlist policy is set to None.
The test case shall pass if the URLs that are part of the URLWhitelist
policy value are not blocked.
The test case shall also pass if the URLs that are not part of the
URLWhitelist policy value are blocked.
The test case shall fail if the above behavior is not enforced.
"""
version = 1
TEST_CASES = {
'NotSet': '',
'SingleWhitelistedFile': SINGLE_WHITELISTED_FILE_DATA,
'MultipleWhitelistedFiles': MULTIPLE_WHITELISTED_FILES_DATA
}
def initialize(self, args=()):
super(policy_URLWhitelist, self).initialize(args)
self.start_webserver(URL_PORT)
def _navigate_to_website(self, url):
"""
Open a new tab in the browser and navigate to the URL.
@param url: the website that the browser is navigated to.
@returns: a chrome browser tab navigated to the URL.
"""
tab = self.cr.browser.tabs.New()
logging.info('Navigating to URL:%s', url)
try:
tab.Navigate(url, timeout=10)
except Exception, err:
logging.error('Timeout Exception in navigating URL: %s\n %s',
url, err)
tab.WaitForDocumentReadyStateToBeComplete()
return tab
def _scrape_text_from_website(self, tab):
"""
Returns a list of the the text content displayed on the page
matching the page_scrape_cmd filter.
@param tab: tab containing the website to be parsed.
@raises: TestFail if the expected text content was not found on the
page.
"""
parsed_message_string = ''
parsed_message_list = []
page_scrape_cmd = 'document.getElementById("main-message").innerText;'
try:
parsed_message_string = tab.EvaluateJavaScript(page_scrape_cmd)
except Exception as err:
raise error.TestFail('Unable to find the expected '
'text content on the test '
'page: %s\n %r'%(tab.url, err))
logging.info('Parsed message:%s', parsed_message_string)
parsed_message_list = [str(word) for word in
parsed_message_string.split('\n') if word]
return parsed_message_list
def _is_url_blocked(self, url):
"""
Returns True if the URL is blocked else returns False.
@param url: The URL to be checked whether it is blocked.
"""
parsed_message_list = []
tab = self._navigate_to_website(url)
parsed_message_list = self._scrape_text_from_website(tab)
if len(parsed_message_list) == 2 and \
parsed_message_list[0] == 'Website enabled' and \
parsed_message_list[1] == 'Website is enabled':
return False
# Check if the accurate user error message displayed on the error page.
if parsed_message_list[0] != BLOCKED_USER_MESSAGE or \
parsed_message_list[1] != BLOCKED_ERROR_MESSAGE:
logging.warning('The Blocked page user notification '
'messages, %s and %s are not displayed on '
'the blocked page. The messages may have '
'been modified. Please check and update the '
'messages in this file accordingly.',
BLOCKED_USER_MESSAGE, BLOCKED_ERROR_MESSAGE)
return True
def _test_URLWhitelist(self, policy_value, policies_json):
"""
Verify CrOS enforces URLWhitelist policy value.
Navigate to all the websites in the BLOCKED_URLS_LIST. Verify that
the websites specified by the URLWhitelist policy value are not
blocked. Also verify that the websites not in the URLWhitelist policy
value are blocked.
@param policy_value: policy value expected on chrome://policy page.
@param policies_json: policy JSON data to send to the fake DM server.
@raises: TestFail if url is blocked/not blocked based on the
corresponding policy values.
"""
url_is_blocked = None
logging.info('Running _test_Whitelist(%s, %s)',
policy_value, policies_json)
self.setup_case(POLICY_NAME, policy_value, policies_json)
for url in BLOCKED_URLS_LIST:
url_is_blocked = self._is_url_blocked(url)
if policy_value:
if url in policy_value and url_is_blocked:
raise error.TestFail('The URL %s should have been allowed'
' by policy, but it was blocked' % url)
elif url not in policy_value and not url_is_blocked:
raise error.TestFail('The URL %s should have been blocked'
' by policy, but it was allowed' % url)
elif not url_is_blocked:
raise error.TestFail('The URL %s should have been blocked'
'by policy, but it was allowed' % url)
def _run_test_case(self, case):
"""
Setup and run the test configured for the specified test case.
Set the expected |policy_value| and |policies_json| data based on the
test |case|. If the user specified an expected |value| in the command
line args, then use it to set the |policy_value| and blank out the
|policies_json|.
@param case: Name of the test case to run.
"""
policy_value = None
policies_json = None
if self.is_value_given:
# If |value| was given in the command line args, then set expected
# |policy_value| to the given value, and |policies_json| to None.
policy_value = self.value
policies_json = None
else:
# Otherwise, set expected |policy_value| and setup |policies_json|
# data to the values required by the specified test |case|.
policies_json = SUPPORTING_POLICIES.copy()
if not self.TEST_CASES[case]:
policy_value = None
else:
policy_value = ','.join(self.TEST_CASES[case])
policies_json.update({'URLWhitelist': self.TEST_CASES[case]})
# Run test using the values configured for the test case.
self._test_URLWhitelist(policy_value, policies_json)
def run_once(self):
self.run_once_impl(self._run_test_case)