Home | History | Annotate | Download | only in policy_URLBlacklist
      1 # Copyright 2015 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 import logging
      6 
      7 from autotest_lib.client.cros import httpd
      8 from autotest_lib.client.common_lib import error
      9 from autotest_lib.client.cros import enterprise_policy_base
     10 
     11 POLICY_NAME = 'URLBlacklist'
     12 URL_HOST = 'http://localhost'
     13 URL_PORT = 8080
     14 URL_BASE = '%s:%d/%s' % (URL_HOST, URL_PORT, 'test_data')
     15 ALL_URLS_LIST = [URL_BASE + website for website in
     16                   ['/website1.html',
     17                    '/website2.html',
     18                    '/website3.html']]
     19 SINGLE_BLACKLISTED_FILE_DATA = ALL_URLS_LIST[:1]
     20 MULTIPLE_BLACKLISTED_FILES_DATA = ALL_URLS_LIST[:2]
     21 BLOCKED_USER_MESSAGE = 'Webpage Blocked'
     22 BLOCKED_ERROR_MESSAGE = 'ERR_BLOCKED_BY_ADMINISTRATOR'
     23 
     24 
     25 class policy_URLBlacklist(enterprise_policy_base.EnterprisePolicyTest):
     26     """
     27     Test effect of URLBlacklist policy on Chrome OS behavior.
     28 
     29     Navigate to each the URLs in the ALL_URLS_LIST and verify that the URLs
     30     specified by the URLBlackList policy are blocked.
     31     Throw a warning if the user message on the blocked page is incorrect.
     32 
     33     Two test cases (SingleBlacklistedFile, MultipleBlacklistedFiles) are
     34     designed to verify that URLs specified in the URLBlacklist policy are
     35     blocked.
     36     The third test case(NotSet) is designed to verify that none of the URLs
     37     are blocked since the URLBlacklist policy is set to None
     38 
     39     The test case shall pass if the URLs that are part of the URLBlacklist
     40     policy value are blocked.
     41     The test case shall also pass if the URLs that are not part of the
     42     URLBlacklist policy value are not blocked.
     43     The test case shall fail if the above behavior is not enforced.
     44 
     45     """
     46     version = 1
     47     TEST_CASES = {
     48         'NotSet': '',
     49         'SingleBlacklistedFile': SINGLE_BLACKLISTED_FILE_DATA,
     50         'MultipleBlacklistedFiles': MULTIPLE_BLACKLISTED_FILES_DATA,
     51     }
     52 
     53     def initialize(self, args=()):
     54         super(policy_URLBlacklist, self).initialize(args)
     55         self.start_webserver(URL_PORT)
     56 
     57     def navigate_to_website(self, url):
     58         """
     59         Open a new tab in the browser and navigate to the URL.
     60 
     61         @param url: the URL that the browser is navigated to.
     62         @returns: a chrome browser tab navigated to the URL.
     63 
     64         """
     65         tab = self.cr.browser.tabs.New()
     66         logging.info('Navigating to URL:%s', url)
     67         try:
     68             tab.Navigate(url, timeout=10)
     69         except Exception, err:
     70             logging.error('Timeout Exception in navigating URL: %s\n %s',
     71                     url, err)
     72         tab.WaitForDocumentReadyStateToBeComplete()
     73         return tab
     74 
     75     def scrape_text_from_website(self, tab):
     76         """
     77         Returns a list of the text content matching the page_scrape_cmd filter.
     78 
     79         @param tab: tab containing the website to be parsed.
     80         @raises: TestFail if the expected text content was not found on the
     81                  page.
     82 
     83         """
     84         parsed_message_string = ''
     85         parsed_message_list = []
     86         page_scrape_cmd = 'document.getElementById("main-message").innerText;'
     87         try:
     88             parsed_message_string = tab.EvaluateJavaScript(page_scrape_cmd)
     89         except Exception as err:
     90                 raise error.TestFail('Unable to find the expected '
     91                         'text content on the test page: %s\n %r'%(tab.url, err))
     92         logging.info('Parsed message:%s', parsed_message_string)
     93         parsed_message_list = [str(word) for word in
     94                                parsed_message_string.split('\n') if word]
     95         return parsed_message_list
     96 
     97     def is_url_blocked(self, url):
     98         """
     99         Returns True if the URL is blocked else returns False.
    100 
    101         @param url: The URL to be checked whether it is blocked.
    102 
    103         """
    104         parsed_message_list = []
    105         tab = self.navigate_to_website(url)
    106         parsed_message_list = self.scrape_text_from_website(tab)
    107         if len(parsed_message_list) == 2 and \
    108                 parsed_message_list[0] == 'Website enabled' and \
    109                 parsed_message_list[1] == 'Website is enabled':
    110             return False
    111 
    112         #Check if the accurate user error message displayed on the error page.
    113         if parsed_message_list[0] != BLOCKED_USER_MESSAGE or \
    114                 parsed_message_list[1] != BLOCKED_ERROR_MESSAGE:
    115             logging.warning('The Blocked page user notification '
    116                             'messages, %s and %s are not displayed on '
    117                             'the blocked page. The messages may have '
    118                             'been modified. Please check and update the '
    119                             'messages in this file accordingly.',
    120                             BLOCKED_USER_MESSAGE, BLOCKED_ERROR_MESSAGE)
    121         return True
    122 
    123     def _test_URLBlacklist(self, policy_value, policies_json):
    124         """
    125         Verify CrOS enforces URLBlacklist policy value.
    126 
    127         When the URLBlacklist policy is set to one or more Domains,
    128         check that navigation to URLs in the Blocked list are blocked.
    129         When set to None, check that none of the websites are blocked.
    130 
    131         @param policy_value: policy value expected on chrome://policy page.
    132         @param policies_json: policy JSON data to send to the fake DM server.
    133         @raises: TestFail if url is blocked/not blocked based on the
    134                  corresponding policy values.
    135 
    136         """
    137         url_is_blocked = None
    138         self.setup_case(POLICY_NAME, policy_value, policies_json)
    139         logging.info('Running _test_URLBlacklist(%s, %s)',
    140                      policy_value, policies_json)
    141 
    142         for url in ALL_URLS_LIST:
    143             url_is_blocked = self.is_url_blocked(url)
    144             if policy_value:
    145                 if url in policy_value and not url_is_blocked:
    146                     raise error.TestFail('The URL %s should have been blocked'
    147                                          ' by policy, but it was allowed' % url)
    148             elif url_is_blocked:
    149                 raise error.TestFail('The URL %s should have been allowed'
    150                                       'by policy, but it was blocked' % url)
    151 
    152     def _run_test_case(self, case):
    153         """
    154         Setup and run the test configured for the specified test case.
    155 
    156         Set the expected |policy_value| and |policies_json| data based on the
    157         test |case|. If the user specified an expected |value| in the command
    158         line args, then use it to set the |policy_value| and blank out the
    159         |policies_json|.
    160 
    161         @param case: Name of the test case to run.
    162 
    163         """
    164         policy_value = None
    165         policies_json = None
    166 
    167         if case not in self.TEST_CASES:
    168             raise error.TestError('Test case %s is not valid.' % case)
    169         logging.info('Running test case: %s', case)
    170 
    171         if self.is_value_given:
    172             # If |value| was given in the command line args, then set expected
    173             # |policy_value| to the given value, and |policies_json| to None.
    174             policy_value = self.value
    175             policies_json = None
    176         else:
    177             # Otherwise, set expected |policy_value| and setup |policies_json|
    178             # data to the values required by the test |case|.
    179             if case == 'NotSet':
    180                 policy_value = None
    181                 policies_json = {'URLBlacklist': None}
    182             elif case == 'SingleBlacklistedFile':
    183                 policy_value = ','.join(SINGLE_BLACKLISTED_FILE_DATA)
    184                 policies_json = {'URLBlacklist': SINGLE_BLACKLISTED_FILE_DATA}
    185 
    186             elif case == 'MultipleBlacklistedFiles':
    187                 policy_value = ','.join(MULTIPLE_BLACKLISTED_FILES_DATA)
    188                 policies_json = {
    189                         'URLBlacklist': MULTIPLE_BLACKLISTED_FILES_DATA
    190                         }
    191 
    192         # Run test using the values configured for the test case.
    193         self._test_URLBlacklist(policy_value, policies_json)
    194 
    195     def run_once(self):
    196             self.run_once_impl(self._run_test_case)
    197