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