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
5import time
6import utils
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros.enterprise import enterprise_policy_base
10
11
12class policy_JavaScriptAllowedForUrls(
13    enterprise_policy_base.EnterprisePolicyTest):
14    """Test JavaScriptAllowedForUrls policy effect on CrOS look & feel.
15
16    This test verifies the behavior of Chrome OS with a range of valid values
17    for the JavaScriptAllowedForUrls user policies. These values are covered
18    by four test cases, named: NotSet_Block, SingleUrl_Allow,
19    MultipleUrls_Block, and MultipleUrls_Allow.
20
21    When the policy value is None (as in case=NotSet_Block), then
22    JavaScript will be blocked on any page. When the value is set to a single
23    URL pattern (as in case=SingleUrl_Allow), JavaScript will be allowed on
24    any page that matches that pattern. When set to multiple URL patterns (as
25    in case=MultipleUrls_Block or MultipleUrls_Allow) then JavaScript will
26    be allowed on any page with a URL that matches any of the listed patterns.
27
28    Two test cases (SingleUrl_Allow, MultipleUrls_Allow) are designed to allow
29    JavaScript to run on the test page. The other two test cases
30    (NotSet_Block, MultipleUrls_Block) are designed to block JavaScript
31    from running on the test page.
32
33    Note this test has a dependency on the DefaultJavaScriptSetting policy,
34    which is partially tested herein, and in policy_JavaScriptBlockedForUrls.
35    For this test, we set DefaultJavaScriptSetting=2. This blocks JavaScript
36    on all pages except those with a URL matching a pattern in
37    JavaScriptAllowedForUrls. For the test policy_JavaScriptBlockedForUrls, we
38    set DefaultJavaScriptSetting=1. That allows JavaScript to be run on all
39    pages except those with URLs that match patterns listed in
40    JavaScriptBlockedForUrls.
41
42    """
43    version = 1
44
45    def initialize(self, **kwargs):
46        """Initialize this test."""
47        self._initialize_test_constants()
48        super(policy_JavaScriptAllowedForUrls, self).initialize(**kwargs)
49        self.start_webserver()
50
51
52    def _initialize_test_constants(self):
53        """Initialize test-specific constants, some from class constants."""
54        self.POLICY_NAME = 'JavaScriptAllowedForUrls'
55        self.TEST_FILE = 'js_test.html'
56        self.TEST_URL = '%s/%s' % (self.WEB_HOST, self.TEST_FILE)
57        self.TEST_CASES = {
58            'NotSet_Block': None,
59            'SingleUrl_Allow': [self.WEB_HOST],
60            'MultipleUrls_Block': ['http://www.bing.com',
61                                   'https://www.yahoo.com'],
62            'MultipleUrls_Allow': ['http://www.bing.com',
63                                   self.TEST_URL,
64                                   'https://www.yahoo.com']
65        }
66
67        self.STARTUP_URLS = ['chrome://policy', 'chrome://settings']
68        self.SUPPORTING_POLICIES = {
69            'DefaultJavaScriptSetting': 2,
70            'BookmarkBarEnabled': False,
71            'RestoreOnStartupURLs': self.STARTUP_URLS,
72            'RestoreOnStartup': 4
73        }
74
75
76    def _can_execute_javascript(self, tab):
77        """Determine whether JavaScript is allowed to run on the given page.
78
79        @param tab: browser tab containing JavaScript to run.
80        """
81        try:
82            utils.poll_for_condition(
83                lambda: tab.EvaluateJavaScript('jsAllowed', timeout=2),
84                exception=error.TestError('Test page is not ready.'))
85            return True
86        except:
87            return False
88
89
90    def _test_javascript_allowed_for_urls(self, policy_value):
91        """Verify CrOS enforces the JavaScriptAllowedForUrls policy.
92
93        When JavaScriptAllowedForUrls is undefined, JavaScript execution shall
94        be blocked on all pages. When JavaScriptAllowedForUrls contains one or
95        more URL patterns, JavaScript execution shall be allowed only on the
96        pages whose URL matches any of the listed patterns.
97
98        Note: This test does not use self.navigate_to_url(), because it can
99        not depend on methods that evaluate or execute JavaScript.
100
101        @param policy_value: policy value for this case.
102        """
103        tab = self.cr.browser.tabs.New()
104        tab.Activate()
105        tab.Navigate(self.TEST_URL)
106        time.sleep(1)
107
108        utils.poll_for_condition(
109            lambda: tab.url == self.TEST_URL,
110            exception=error.TestError('Test page is not ready.'))
111        javascript_is_allowed = self._can_execute_javascript(tab)
112
113        if policy_value is not None and (self.WEB_HOST in policy_value or
114                                         self.TEST_URL in policy_value):
115            # If |WEB_HOST| is in |policy_value|, then JavaScript execution
116            # should be allowed. If execution is blocked, raise an error.
117            if not javascript_is_allowed:
118                raise error.TestFail('JavaScript should be allowed.')
119        else:
120            if javascript_is_allowed:
121                raise error.TestFail('JavaScript should be blocked.')
122        tab.Close()
123
124
125    def run_once(self, case):
126        """Setup and run the test configured for the specified test case.
127
128        @param case: Name of the test case to run.
129
130        """
131        case_value = self.TEST_CASES[case]
132        self.SUPPORTING_POLICIES[self.POLICY_NAME] = case_value
133        self.setup_case(user_policies=self.SUPPORTING_POLICIES)
134        self._test_javascript_allowed_for_urls(case_value)
135