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