Upstream version 7.36.149.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     expectLE(this.stsObserved_, result.dynamic_sts_observed);
128     expectLE(this.pkpObserved_, result.dynamic_pkp_observed);
129
130     // |public_key_hashes| is an old synonym for what is now
131     // |preloaded_spki_hashes|, which in turn is a legacy synonym for
132     // |static_spki_hashes|. Look for all three, and also for
133     // |dynamic_spki_hashes|.
134     if (typeof result.public_key_hashes === 'undefined')
135       result.public_key_hashes = '';
136     if (typeof result.preloaded_spki_hashes === 'undefined')
137       result.preloaded_spki_hashes = '';
138     if (typeof result.static_spki_hashes === 'undefined')
139       result.static_spki_hashes = '';
140     if (typeof result.dynamic_spki_hashes === 'undefined')
141       result.dynamic_spki_hashes = '';
142
143     var hashes = [];
144     if (result.public_key_hashes)
145       hashes.push(result.public_key_hashes);
146     if (result.preloaded_spki_hashes)
147       hashes.push(result.preloaded_spki_hashes);
148     if (result.static_spki_hashes)
149       hashes.push(result.static_spki_hashes);
150     if (result.dynamic_spki_hashes)
151       hashes.push(result.dynamic_spki_hashes);
152
153     expectEquals(this.publicKeyHashes_, hashes.join(','));
154
155     // Verify that the domain appears somewhere in the displayed text.
156     outputText = $(HSTSView.QUERY_OUTPUT_DIV_ID).innerText;
157     expectLE(0, outputText.search(this.domain_));
158   }
159 };
160
161 /**
162  * A Task to try and add an HSTS domain via the HTML form.  The task will wait
163  * until the results from the automatically sent query have been received, and
164  * then checks them against the expected values.
165  * @param {string} domain The domain to send and expected to be returned.
166  * @param {bool} stsSubdomains Whether the HSTS subdomain checkbox should be
167  *     selected. Also the corresponding expected return value, in the success
168  *     case.
169  * @param {bool} pkpSubdomains Whether the pinning subdomain checkbox should be
170  *     selected. Also the corresponding expected return value, in the success
171  *     case.
172  * @param {number} stsObserved The time the STS policy was observed.
173  * @param {number} pkpObserved The time the PKP policy was observed.
174  * @param {string} publicKeyHashes Public key hash to send.  Also the
175  *     corresponding expected return value, on success.  When this is the string
176  *     INVALID_HASH, an empty string is expected to be received instead.
177  * @param {QueryResultType} queryResultType Expected result type.
178  * @extends {CheckQueryResultTask}
179  */
180 function AddTask(domain, stsSubdomains, pkpSubdomains, publicKeyHashes,
181                  stsObserved, pkpObserved, queryResultType) {
182   this.requestedPublicKeyHashes_ = publicKeyHashes;
183   if (publicKeyHashes == INVALID_HASH)
184     publicKeyHashes = '';
185   CheckQueryResultTask.call(this, domain, stsSubdomains, pkpSubdomains,
186                             stsObserved, pkpObserved, publicKeyHashes,
187                             queryResultType);
188 }
189
190 AddTask.prototype = {
191   __proto__: CheckQueryResultTask.prototype,
192
193   /**
194    * Fills out the add form, simulates a click to submit it, and starts
195    * listening for the results of the query that is automatically submitted.
196    */
197   start: function() {
198     $(HSTSView.ADD_INPUT_ID).value = this.domain_;
199     $(HSTSView.ADD_STS_CHECK_ID).checked = this.stsSubdomains_;
200     $(HSTSView.ADD_PKP_CHECK_ID).checked = this.pkpSubdomains_;
201     $(HSTSView.ADD_PINS_ID).value = this.requestedPublicKeyHashes_;
202     $(HSTSView.ADD_SUBMIT_ID).click();
203     CheckQueryResultTask.prototype.start.call(this);
204   }
205 };
206
207 /**
208  * A Task to query a domain and wait for the results.  Parameters mirror those
209  * of CheckQueryResultTask, except |domain| is also the name of the domain to
210  * query.
211  * @extends {CheckQueryResultTask}
212  */
213 function QueryTask(domain, stsSubdomains, pkpSubdomains, stsObserved,
214                    pkpObserved, publicKeyHashes, queryResultType) {
215   CheckQueryResultTask.call(this, domain, stsSubdomains, pkpSubdomains,
216                             stsObserved, pkpObserved, publicKeyHashes,
217                             queryResultType);
218 }
219
220 QueryTask.prototype = {
221   __proto__: CheckQueryResultTask.prototype,
222
223   /**
224    * Fills out the query form, simulates a click to submit it, and starts
225    * listening for the results.
226    */
227   start: function() {
228     CheckQueryResultTask.prototype.start.call(this);
229     $(HSTSView.QUERY_INPUT_ID).value = this.domain_;
230     $(HSTSView.QUERY_SUBMIT_ID).click();
231   }
232 };
233
234 /**
235  * Task that deletes a single domain, then queries the deleted domain to make
236  * sure it's gone.
237  * @param {string} domain The domain to delete.
238  * @param {QueryResultType} queryResultType The result of the query.  Can be
239  *     QueryResultType.ERROR or QueryResultType.NOT_FOUND.
240  * @extends {QueryTask}
241  */
242 function DeleteTask(domain, queryResultType) {
243   expectNotEquals(queryResultType, QueryResultType.SUCCESS);
244   this.domain_ = domain;
245   QueryTask.call(this, domain, false, false, '', 0, 0, queryResultType);
246 }
247
248 DeleteTask.prototype = {
249   __proto__: QueryTask.prototype,
250
251   /**
252    * Fills out the delete form and simulates a click to submit it.  Then sends
253    * a query.
254    */
255   start: function() {
256     $(HSTSView.DELETE_INPUT_ID).value = this.domain_;
257     $(HSTSView.DELETE_SUBMIT_ID).click();
258     QueryTask.prototype.start.call(this);
259   }
260 };
261
262 /**
263  * Checks that querying a domain that was never added fails.
264  */
265 TEST_F('NetInternalsTest', 'netInternalsHSTSViewQueryNotFound', function() {
266   NetInternalsTest.switchToView('hsts');
267   taskQueue = new NetInternalsTest.TaskQueue(true);
268   var now = new Date().getTime() / 1000.0;
269   taskQueue.addTask(new QueryTask('somewhere.com', false, false, now, now, '',
270                                   QueryResultType.NOT_FOUND));
271   taskQueue.run();
272 });
273
274 /**
275  * Checks that querying a domain with an invalid name returns an error.
276  */
277 TEST_F('NetInternalsTest', 'netInternalsHSTSViewQueryError', function() {
278   NetInternalsTest.switchToView('hsts');
279   taskQueue = new NetInternalsTest.TaskQueue(true);
280   var now = new Date().getTime() / 1000.0;
281   taskQueue.addTask(new QueryTask('\u3024', false, false, now, now, '',
282                                   QueryResultType.ERROR));
283   taskQueue.run();
284 });
285
286 /**
287  * Deletes a domain that was never added.
288  */
289 TEST_F('NetInternalsTest', 'netInternalsHSTSViewDeleteNotFound', function() {
290   NetInternalsTest.switchToView('hsts');
291   taskQueue = new NetInternalsTest.TaskQueue(true);
292   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
293   taskQueue.run();
294 });
295
296 /**
297  * Deletes a domain that returns an error on lookup.
298  */
299 TEST_F('NetInternalsTest', 'netInternalsHSTSViewDeleteError', function() {
300   NetInternalsTest.switchToView('hsts');
301   taskQueue = new NetInternalsTest.TaskQueue(true);
302   taskQueue.addTask(new DeleteTask('\u3024', QueryResultType.ERROR));
303   taskQueue.run();
304 });
305
306 /**
307  * Adds a domain and then deletes it.
308  */
309 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddDelete', function() {
310   NetInternalsTest.switchToView('hsts');
311   taskQueue = new NetInternalsTest.TaskQueue(true);
312   var now = new Date().getTime() / 1000.0;
313   taskQueue.addTask(new AddTask('somewhere.com', false, false, VALID_HASH,
314                                 now, now, QueryResultType.SUCCESS));
315   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
316   taskQueue.run();
317 });
318
319 /**
320  * Tries to add a domain with an invalid name.
321  */
322 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddFail', function() {
323   NetInternalsTest.switchToView('hsts');
324   taskQueue = new NetInternalsTest.TaskQueue(true);
325   var now = new Date().getTime() / 1000.0;
326   taskQueue.addTask(new AddTask('0123456789012345678901234567890' +
327                                 '012345678901234567890123456789012345',
328                                 false, false, '', now, now,
329                                 QueryResultType.NOT_FOUND));
330   taskQueue.run();
331 });
332
333 /**
334  * Tries to add a domain with a name that errors out on lookup due to having
335  * non-ASCII characters in it.
336  */
337 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddError', function() {
338   NetInternalsTest.switchToView('hsts');
339   taskQueue = new NetInternalsTest.TaskQueue(true);
340   var now = new Date().getTime() / 1000.0;
341   taskQueue.addTask(new AddTask('\u3024', false, false, '', now, now,
342                                 QueryResultType.ERROR));
343   taskQueue.run();
344 });
345
346 /**
347  * Adds a domain with an invalid hash.
348  */
349 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddInvalidHash', function() {
350   NetInternalsTest.switchToView('hsts');
351   taskQueue = new NetInternalsTest.TaskQueue(true);
352   var now = new Date().getTime() / 1000.0;
353   taskQueue.addTask(new AddTask('somewhere.com', true, true, INVALID_HASH,
354                                 now, now, QueryResultType.SUCCESS));
355   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
356   taskQueue.run();
357 });
358
359 /**
360  * Adds the same domain twice in a row, modifying some values the second time.
361  */
362 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddOverwrite', function() {
363   NetInternalsTest.switchToView('hsts');
364   taskQueue = new NetInternalsTest.TaskQueue(true);
365   var now = new Date().getTime() / 1000.0;
366   taskQueue.addTask(new AddTask('somewhere.com', true, true, VALID_HASH,
367                                 now, now, QueryResultType.SUCCESS));
368   taskQueue.addTask(new AddTask('somewhere.com', false, false, '',
369                                 now, now, QueryResultType.SUCCESS));
370   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
371   taskQueue.run();
372 });
373
374 /**
375  * Adds two different domains and then deletes them.
376  */
377 TEST_F('NetInternalsTest', 'netInternalsHSTSViewAddTwice', function() {
378   NetInternalsTest.switchToView('hsts');
379   taskQueue = new NetInternalsTest.TaskQueue(true);
380   var now = new Date().getTime() / 1000.0;
381   taskQueue.addTask(new AddTask('somewhere.com', false, false, VALID_HASH,
382                                 now, now, QueryResultType.SUCCESS));
383   taskQueue.addTask(new QueryTask('somewhereelse.com', false, false, now, now,
384                                   '', QueryResultType.NOT_FOUND));
385   taskQueue.addTask(new AddTask('somewhereelse.com', true, true, '',
386                                 now, now, QueryResultType.SUCCESS));
387   taskQueue.addTask(new QueryTask('somewhere.com', false, false, now, now,
388                                   VALID_HASH, QueryResultType.SUCCESS));
389   taskQueue.addTask(new DeleteTask('somewhere.com', QueryResultType.NOT_FOUND));
390   taskQueue.addTask(new QueryTask('somewhereelse.com', true, true, now, now, '',
391                                   QueryResultType.SUCCESS));
392   taskQueue.addTask(new DeleteTask('somewhereelse.com',
393                                    QueryResultType.NOT_FOUND));
394   taskQueue.run(true);
395 });
396
397 })();  // Anonymous namespace