Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / webui / net_internals / hsts_view.js
1 // Copyright (c) 2012 The Chromium 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 // Include test fixture.
6 GEN_INCLUDE(['net_internals_test.js']);
7
8 // Anonymous namespace
9 (function() {
10
11 /*
12  * A valid hash that can be set for a domain.
13  * @type {string}
14  */
15 var VALID_HASH = 'sha1/Guzek9lMwR3KeIS8wwS9gBvVtIg=';
16
17 /*
18  * An invalid hash that can't be set for a domain.
19  * @type {string}
20  */
21 var INVALID_HASH = 'invalid';
22
23 /*
24  * Possible results of an HSTS query.
25  * @enum {number}
26  */
27 var QueryResultType = {
28   SUCCESS: 0,
29   NOT_FOUND: 1,
30   ERROR: 2
31 };
32
33 /**
34  * A Task that waits for the results of an HSTS query.  Once the results are
35  * received, checks them before completing.  Does not initiate the query.
36  * @param {string} domain The domain expected in the returned results.
37  * @param {bool} stsSubdomains Whether or not the stsSubdomains flag is expected
38  *     to be set in the returned results.  Ignored on error and not found
39  *     results.
40  * @param {bool} pkpSubdomains Whether or not the pkpSubdomains flag is expected
41  *     to be set in the returned results.  Ignored on error and not found
42  *     results.
43  * @param {number} stsObserved The time the STS policy was observed.
44  * @param {number} pkpObserved The time the PKP policy was observed.
45  * @param {string} publicKeyHashes Expected public key hashes.  Ignored on error
46  *     error and not found results.
47  * @param {QueryResultType} queryResultType The expected result type of the
48  *     results of the query.
49  * @extends {NetInternalsTest.Task}
50  */
51 function CheckQueryResultTask(domain, stsSubdomains, pkpSubdomains,
52                               stsObserved, pkpObserved, publicKeyHashes,
53                               queryResultType) {
54   this.domain_ = domain;
55   this.stsSubdomains_ = stsSubdomains;
56   this.pkpSubdomains_ = pkpSubdomains;
57   this.stsObserved_ = stsObserved;
58   this.pkpObserved_ = pkpObserved;
59   this.publicKeyHashes_ = publicKeyHashes;
60   this.queryResultType_ = queryResultType;
61   NetInternalsTest.Task.call(this);
62 }
63
64 CheckQueryResultTask.prototype = {
65   __proto__: NetInternalsTest.Task.prototype,
66
67   /**
68    * Starts watching for the query results.
69    */
70   start: function() {
71     g_browser.addHSTSObserver(this);
72   },
73
74   /**
75    * Callback from the BrowserBridge.  Validates |result| and completes the
76    * task.
77    * @param {object} result Results from the query.
78    */
79   onHSTSQueryResult: function(result) {
80     // Ignore results after |this| is finished.
81     if (!this.isDone()) {
82       expectEquals(this.domain_, $(HSTSView.QUERY_INPUT_ID).value);
83
84       // Each case has its own validation function because of the design of the
85       // test reporting infrastructure.
86       if (result.error != undefined) {
87         this.checkError_(result);
88       } else if (!result.result) {
89         this.checkNotFound_(result);
90       } else {
91         this.checkSuccess_(result);
92       }
93       this.running_ = false;
94
95       // Start the next task asynchronously, so it can add another HSTS observer
96       // without getting the current result.
97       window.setTimeout(this.onTaskDone.bind(this), 1);
98     }
99   },
100
101   /**
102    * On errors, checks the result.
103    * @param {object} result Results from the query.
104    */
105   checkError_: function(result) {
106     expectEquals(QueryResultType.ERROR, this.queryResultType_);
107     expectEquals(result.error, $(HSTSView.QUERY_OUTPUT_DIV_ID).innerText);
108   },
109
110   /**
111    * Checks the result when the entry was not found.
112    * @param {object} result Results from the query.
113    */
114   checkNotFound_: function(result) {
115     expectEquals(QueryResultType.NOT_FOUND, this.queryResultType_);
116     expectEquals('Not found', $(HSTSView.QUERY_OUTPUT_DIV_ID).innerText);
117   },
118
119   /**
120    * Checks successful results.
121    * @param {object} result Results from the query.
122    */
123   checkSuccess_: function(result) {
124     expectEquals(QueryResultType.SUCCESS, this.queryResultType_);
125     expectEquals(this.stsSubdomains_, result.dynamic_sts_include_subdomains);
126     expectEquals(this.pkpSubdomains_, result.dynamic_pkp_include_subdomains);
127     // Disabled because of http://crbug.com/397639
128     // expectLE(this.stsObserved_, result.dynamic_sts_observed);
129     // expectLE(this.pkpObserved_, result.dynamic_pkp_observed);
130
131     // |public_key_hashes| is an old synonym for what is now
132     // |preloaded_spki_hashes|, which in turn is a legacy synonym for
133     // |static_spki_hashes|. Look for all three, and also for
134     // |dynamic_spki_hashes|.
135     if (typeof result.public_key_hashes === 'undefined')
136       result.public_key_hashes = '';
137     if (typeof result.preloaded_spki_hashes === 'undefined')
138       result.preloaded_spki_hashes = '';
139     if (typeof result.static_spki_hashes === 'undefined')
140       result.static_spki_hashes = '';
141     if (typeof result.dynamic_spki_hashes === 'undefined')
142       result.dynamic_spki_hashes = '';
143
144     var hashes = [];
145     if (result.public_key_hashes)
146       hashes.push(result.public_key_hashes);
147     if (result.preloaded_spki_hashes)
148       hashes.push(result.preloaded_spki_hashes);
149     if (result.static_spki_hashes)
150       hashes.push(result.static_spki_hashes);
151     if (result.dynamic_spki_hashes)
152       hashes.push(result.dynamic_spki_hashes);
153
154     expectEquals(this.publicKeyHashes_, hashes.join(','));
155
156     // Verify that the domain appears somewhere in the displayed text.
157     outputText = $(HSTSView.QUERY_OUTPUT_DIV_ID).innerText;
158     expectLE(0, outputText.search(this.domain_));
159   }
160 };
161
162 /**
163  * A Task to try and add an HSTS domain via the HTML form.  The task will wait
164  * until the results from the automatically sent query have been received, and
165  * then checks them against the expected values.
166  * @param {string} domain The domain to send and expected to be returned.
167  * @param {bool} stsSubdomains Whether the HSTS subdomain checkbox should be
168  *     selected. Also the corresponding expected return value, in the success
169  *     case.
170  * @param {bool} pkpSubdomains Whether the pinning subdomain checkbox should be
171  *     selected. Also the corresponding expected return value, in the success
172  *     case.
173  * @param {number} stsObserved The time the STS policy was observed.
174  * @param {number} pkpObserved The time the PKP policy was observed.
175  * @param {string} publicKeyHashes Public key hash to send.  Also the
176  *     corresponding expected return value, on success.  When this is the string
177  *     INVALID_HASH, an empty string is expected to be received instead.
178  * @param {QueryResultType} queryResultType Expected result type.
179  * @extends {CheckQueryResultTask}
180  */
181 function AddTask(domain, stsSubdomains, pkpSubdomains, publicKeyHashes,
182                  stsObserved, pkpObserved, queryResultType) {
183   this.requestedPublicKeyHashes_ = publicKeyHashes;
184   if (publicKeyHashes == INVALID_HASH)
185     publicKeyHashes = '';
186   CheckQueryResultTask.call(this, domain, stsSubdomains, pkpSubdomains,
187                             stsObserved, pkpObserved, publicKeyHashes,
188                             queryResultType);
189 }
190
191 AddTask.prototype = {
192   __proto__: CheckQueryResultTask.prototype,
193
194   /**
195    * Fills out the add form, simulates a click to submit it, and starts
196    * listening for the results of the query that is automatically submitted.
197    */
198   start: function() {
199     $(HSTSView.ADD_INPUT_ID).value = this.domain_;
200     $(HSTSView.ADD_STS_CHECK_ID).checked = this.stsSubdomains_;
201     $(HSTSView.ADD_PKP_CHECK_ID).checked = this.pkpSubdomains_;
202     $(HSTSView.ADD_PINS_ID).value = this.requestedPublicKeyHashes_;
203     $(HSTSView.ADD_SUBMIT_ID).click();
204     CheckQueryResultTask.prototype.start.call(this);
205   }
206 };
207
208 /**
209  * A Task to query a domain and wait for the results.  Parameters mirror those
210  * of CheckQueryResultTask, except |domain| is also the name of the domain to
211  * query.
212  * @extends {CheckQueryResultTask}
213  */
214 function QueryTask(domain, stsSubdomains, pkpSubdomains, stsObserved,
215                    pkpObserved, publicKeyHashes, queryResultType) {
216   CheckQueryResultTask.call(this, domain, stsSubdomains, pkpSubdomains,
217                             stsObserved, pkpObserved, publicKeyHashes,
218                             queryResultType);
219 }
220
221 QueryTask.prototype = {
222   __proto__: CheckQueryResultTask.prototype,
223
224   /**
225    * Fills out the query form, simulates a click to submit it, and starts
226    * listening for the results.
227    */
228   start: function() {
229     CheckQueryResultTask.prototype.start.call(this);
230     $(HSTSView.QUERY_INPUT_ID).value = this.domain_;
231     $(HSTSView.QUERY_SUBMIT_ID).click();
232   }
233 };
234
235 /**
236  * Task that deletes a single domain, then queries the deleted domain to make
237  * sure it's gone.
238  * @param {string} domain The domain to delete.
239  * @param {QueryResultType} queryResultType The result of the query.  Can be
240  *     QueryResultType.ERROR or QueryResultType.NOT_FOUND.
241  * @extends {QueryTask}
242  */
243 function DeleteTask(domain, queryResultType) {
244   expectNotEquals(queryResultType, QueryResultType.SUCCESS);
245   this.domain_ = domain;
246   QueryTask.call(this, domain, false, false, '', 0, 0, queryResultType);
247 }
248
249 DeleteTask.prototype = {
250   __proto__: QueryTask.prototype,
251
252   /**
253    * Fills out the delete form and simulates a click to submit it.  Then sends
254    * a query.
255    */
256   start: function() {
257     $(HSTSView.DELETE_INPUT_ID).value = this.domain_;
258     $(HSTSView.DELETE_SUBMIT_ID).click();
259     QueryTask.prototype.start.call(this);
260   }
261 };
262
263 /**
264  * Checks that querying a domain that was never added fails.
265  */
266 TEST_F('NetInternalsTest', 'netInternalsHSTSViewQueryNotFound', function() {
267   NetInternalsTest.switchToView('hsts');
268   taskQueue = new NetInternalsTest.TaskQueue(true);
269   var now = new Date().getTime() / 1000.0;
270   taskQueue.addTask(new QueryTask('somewhere.com', false, false, now, now, '',
271                                   QueryResultType.NOT_FOUND));
272   taskQueue.run();
273 });
274
275 /**
276  * Checks that querying a domain with an invalid name returns an error.
277  */
278 TEST_F('NetInternalsTest', 'netInternalsHSTSViewQueryError', function() {
279   NetInternalsTest.switchToView('hsts');
280   taskQueue = new NetInternalsTest.TaskQueue(true);
281   var now = new Date().getTime() / 1000.0;
282   taskQueue.addTask(new QueryTask('\u3024', false, false, now, now, '',
283                                   QueryResultType.ERROR));
284   taskQueue.run();
285 });
286
287 /**
288  * Deletes a domain that was never added.
289  */
290 TEST_F('NetInternalsTest', 'netInternalsHSTSViewDeleteNotFound', function() {
291   NetInternalsTest.switchToView('hsts');
292   taskQueue = new NetInternalsTest.TaskQueue(true);
293   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
294   taskQueue.run();
295 });
296
297 /**
298  * Deletes a domain that returns an error on lookup.
299  */
300 TEST_F('NetInternalsTest', 'netInternalsHSTSViewDeleteError', function() {
301   NetInternalsTest.switchToView('hsts');
302   taskQueue = new NetInternalsTest.TaskQueue(true);
303   taskQueue.addTask(new DeleteTask('\u3024', QueryResultType.ERROR));
304   taskQueue.run();
305 });
306
307 /**
308  * Adds a domain and then deletes it.
309  */
310 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddDelete', function() {
311   NetInternalsTest.switchToView('hsts');
312   taskQueue = new NetInternalsTest.TaskQueue(true);
313   var now = new Date().getTime() / 1000.0;
314   taskQueue.addTask(new AddTask('somewhere.com', false, false, VALID_HASH,
315                                 now, now, QueryResultType.SUCCESS));
316   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
317   taskQueue.run();
318 });
319
320 /**
321  * Tries to add a domain with an invalid name.
322  */
323 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddFail', function() {
324   NetInternalsTest.switchToView('hsts');
325   taskQueue = new NetInternalsTest.TaskQueue(true);
326   var now = new Date().getTime() / 1000.0;
327   taskQueue.addTask(new AddTask('0123456789012345678901234567890' +
328                                 '012345678901234567890123456789012345',
329                                 false, false, '', now, now,
330                                 QueryResultType.NOT_FOUND));
331   taskQueue.run();
332 });
333
334 /**
335  * Tries to add a domain with a name that errors out on lookup due to having
336  * non-ASCII characters in it.
337  */
338 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddError', function() {
339   NetInternalsTest.switchToView('hsts');
340   taskQueue = new NetInternalsTest.TaskQueue(true);
341   var now = new Date().getTime() / 1000.0;
342   taskQueue.addTask(new AddTask('\u3024', false, false, '', now, now,
343                                 QueryResultType.ERROR));
344   taskQueue.run();
345 });
346
347 /**
348  * Adds a domain with an invalid hash.
349  */
350 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddInvalidHash', function() {
351   NetInternalsTest.switchToView('hsts');
352   taskQueue = new NetInternalsTest.TaskQueue(true);
353   var now = new Date().getTime() / 1000.0;
354   taskQueue.addTask(new AddTask('somewhere.com', true, true, INVALID_HASH,
355                                 now, now, QueryResultType.SUCCESS));
356   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
357   taskQueue.run();
358 });
359
360 /**
361  * Adds the same domain twice in a row, modifying some values the second time.
362  */
363 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddOverwrite', function() {
364   NetInternalsTest.switchToView('hsts');
365   taskQueue = new NetInternalsTest.TaskQueue(true);
366   var now = new Date().getTime() / 1000.0;
367   taskQueue.addTask(new AddTask('somewhere.com', true, true, VALID_HASH,
368                                 now, now, QueryResultType.SUCCESS));
369   taskQueue.addTask(new AddTask('somewhere.com', false, false, '',
370                                 now, now, QueryResultType.SUCCESS));
371   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
372   taskQueue.run();
373 });
374
375 /**
376  * Adds two different domains and then deletes them.
377  */
378 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddTwice', function() {
379   NetInternalsTest.switchToView('hsts');
380   taskQueue = new NetInternalsTest.TaskQueue(true);
381   var now = new Date().getTime() / 1000.0;
382   taskQueue.addTask(new AddTask('somewhere.com', false, false, VALID_HASH,
383                                 now, now, QueryResultType.SUCCESS));
384   taskQueue.addTask(new QueryTask('somewhereelse.com', false, false, now, now,
385                                   '', QueryResultType.NOT_FOUND));
386   taskQueue.addTask(new AddTask('somewhereelse.com', true, true, '',
387                                 now, now, QueryResultType.SUCCESS));
388   taskQueue.addTask(new QueryTask('somewhere.com', false, false, now, now,
389                                   VALID_HASH, QueryResultType.SUCCESS));
390   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
391   taskQueue.addTask(new QueryTask('somewhereelse.com', true, true, now, now, '',
392                                   QueryResultType.SUCCESS));
393   taskQueue.addTask(new DeleteTask('somewhereelse.com',
394                                    QueryResultType.NOT_FOUND));
395   taskQueue.run(true);
396 });
397
398 })();  // Anonymous namespace