Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(454)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 /** 4 /**
6 * @constructor
7 * @extends {WebInspector.PanelWithSidebar}
8 * @implements {WebInspector.TargetManager.Observer} 5 * @implements {WebInspector.TargetManager.Observer}
6 * @unrestricted
9 */ 7 */
10 WebInspector.SecurityPanel = function() 8 WebInspector.SecurityPanel = class extends WebInspector.PanelWithSidebar {
11 { 9 constructor() {
12 WebInspector.PanelWithSidebar.call(this, "security"); 10 super('security');
13 11
14 this._mainView = new WebInspector.SecurityMainView(this); 12 this._mainView = new WebInspector.SecurityMainView(this);
15 13
16 this._sidebarMainViewElement = new WebInspector.SecurityPanelSidebarTreeElem ent(WebInspector.UIString("Overview"), this._setVisibleView.bind(this, this._mai nView), "security-main-view-sidebar-tree-item", "lock-icon"); 14 this._sidebarMainViewElement = new WebInspector.SecurityPanelSidebarTreeElem ent(
17 this._sidebarTree = new WebInspector.SecurityPanelSidebarTree(this._sidebarM ainViewElement, this.showOrigin.bind(this)); 15 WebInspector.UIString('Overview'), this._setVisibleView.bind(this, this. _mainView),
16 'security-main-view-sidebar-tree-item', 'lock-icon');
17 this._sidebarTree =
18 new WebInspector.SecurityPanelSidebarTree(this._sidebarMainViewElement, this.showOrigin.bind(this));
18 this.panelSidebarElement().appendChild(this._sidebarTree.element); 19 this.panelSidebarElement().appendChild(this._sidebarTree.element);
19 20
20 /** @type {!Map<!NetworkAgent.LoaderId, !WebInspector.NetworkRequest>} */ 21 /** @type {!Map<!NetworkAgent.LoaderId, !WebInspector.NetworkRequest>} */
21 this._lastResponseReceivedForLoaderId = new Map(); 22 this._lastResponseReceivedForLoaderId = new Map();
22 23
23 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa nel.OriginState>} */ 24 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa nel.OriginState>} */
24 this._origins = new Map(); 25 this._origins = new Map();
25 26
26 /** @type {!Map<!WebInspector.NetworkLogView.MixedContentFilterValues, numbe r>} */ 27 /** @type {!Map<!WebInspector.NetworkLogView.MixedContentFilterValues, numbe r>} */
27 this._filterRequestCounts = new Map(); 28 this._filterRequestCounts = new Map();
28 29
29 /** @type {!Map<!WebInspector.Target, !Array<!WebInspector.EventTarget.Event Descriptor>>}*/ 30 /** @type {!Map<!WebInspector.Target, !Array<!WebInspector.EventTarget.Event Descriptor>>}*/
30 this._eventListeners = new Map(); 31 this._eventListeners = new Map();
31 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili ty.Network); 32 WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capabili ty.Network);
33 }
34
35 /**
36 * @return {!WebInspector.SecurityPanel}
37 */
38 static _instance() {
39 return /** @type {!WebInspector.SecurityPanel} */ (self.runtime.sharedInstan ce(WebInspector.SecurityPanel));
40 }
41
42 /**
43 * @param {string} text
44 * @param {!WebInspector.SecurityPanel} panel
45 * @return {!Element}
46 */
47 static createCertificateViewerButton(text, panel) {
48 /**
49 * @param {!Event} e
50 */
51 function showCertificateViewer(e) {
52 e.consume();
53 panel.showCertificateViewer();
54 }
55
56 return createTextButton(text, showCertificateViewer, 'security-certificate-b utton');
57 }
58
59 /**
60 * @param {string} text
61 * @param {string} origin
62 * @return {!Element}
63 */
64 static createCertificateViewerButton2(text, origin) {
65 /**
66 * @param {!Event} e
67 */
68 function showCertificateViewer(e) {
69 function certificateCallback(names) {
70 InspectorFrontendHost.showCertificateViewer(names);
71 }
72
73 e.consume();
74 WebInspector.multitargetNetworkManager.getCertificate(origin, certificateC allback);
75 }
76
77 return createTextButton(text, showCertificateViewer, 'security-certificate-b utton');
78 }
79
80 /**
81 * @param {!SecurityAgent.SecurityState} securityState
82 */
83 setRanInsecureContentStyle(securityState) {
84 this._ranInsecureContentStyle = securityState;
85 }
86
87 /**
88 * @param {!SecurityAgent.SecurityState} securityState
89 */
90 setDisplayedInsecureContentStyle(securityState) {
91 this._displayedInsecureContentStyle = securityState;
92 }
93
94 /**
95 * @param {!SecurityAgent.SecurityState} newSecurityState
96 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
97 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus
98 * @param {boolean} schemeIsCryptographic
99 */
100 _updateSecurityState(newSecurityState, explanations, insecureContentStatus, sc hemeIsCryptographic) {
101 this._sidebarMainViewElement.setSecurityState(newSecurityState);
102 this._mainView.updateSecurityState(newSecurityState, explanations, insecureC ontentStatus, schemeIsCryptographic);
103 }
104
105 /**
106 * @param {!WebInspector.Event} event
107 */
108 _onSecurityStateChanged(event) {
109 var data = /** @type {!WebInspector.PageSecurityState} */ (event.data);
110 var securityState = /** @type {!SecurityAgent.SecurityState} */ (data.securi tyState);
111 var explanations = /** @type {!Array<!SecurityAgent.SecurityStateExplanation >} */ (data.explanations);
112 var insecureContentStatus = /** @type {?SecurityAgent.InsecureContentStatus} */ (data.insecureContentStatus);
113 var schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptograph ic);
114 this._updateSecurityState(securityState, explanations, insecureContentStatus , schemeIsCryptographic);
115 }
116
117 selectAndSwitchToMainView() {
118 // The sidebar element will trigger displaying the main view. Rather than ma king a redundant call to display the main view, we rely on this.
119 this._sidebarMainViewElement.select();
120 }
121 /**
122 * @param {!WebInspector.SecurityPanel.Origin} origin
123 */
124 showOrigin(origin) {
125 var originState = this._origins.get(origin);
126 if (!originState.originView)
127 originState.originView = new WebInspector.SecurityOriginView(this, origin, originState);
128
129 this._setVisibleView(originState.originView);
130 }
131
132 /**
133 * @override
134 */
135 wasShown() {
136 super.wasShown();
137 if (!this._visibleView)
138 this.selectAndSwitchToMainView();
139 }
140
141 /**
142 * @override
143 */
144 focus() {
145 this._sidebarTree.focus();
146 }
147
148 /**
149 * @param {!WebInspector.VBox} view
150 */
151 _setVisibleView(view) {
152 if (this._visibleView === view)
153 return;
154
155 if (this._visibleView)
156 this._visibleView.detach();
157
158 this._visibleView = view;
159
160 if (view)
161 this.splitWidget().setMainWidget(view);
162 }
163
164 /**
165 * @param {!WebInspector.Event} event
166 */
167 _onResponseReceived(event) {
168 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
169 if (request.resourceType() === WebInspector.resourceTypes.Document)
170 this._lastResponseReceivedForLoaderId.set(request.loaderId, request);
171 }
172
173 /**
174 * @param {!WebInspector.NetworkRequest} request
175 */
176 _processRequest(request) {
177 var origin = WebInspector.ParsedURL.extractOrigin(request.url);
178
179 if (!origin) {
180 // We don't handle resources like data: URIs. Most of them don't affect th e lock icon.
181 return;
182 }
183
184 var securityState = /** @type {!SecurityAgent.SecurityState} */ (request.sec urityState());
185
186 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Blocka ble && this._ranInsecureContentStyle)
187 securityState = this._ranInsecureContentStyle;
188 else if (
189 request.mixedContentType === NetworkAgent.RequestMixedContentType.Option allyBlockable &&
190 this._displayedInsecureContentStyle)
191 securityState = this._displayedInsecureContentStyle;
192
193 if (this._origins.has(origin)) {
194 var originState = this._origins.get(origin);
195 var oldSecurityState = originState.securityState;
196 originState.securityState = this._securityStateMin(oldSecurityState, secur ityState);
197 if (oldSecurityState !== originState.securityState) {
198 this._sidebarTree.updateOrigin(origin, securityState);
199 if (originState.originView)
200 originState.originView.setSecurityState(securityState);
201 }
202 } else {
203 // TODO(lgarron): Store a (deduplicated) list of different security detail s we have seen. https://crbug.com/503170
204 var originState = {};
205 originState.securityState = securityState;
206
207 var securityDetails = request.securityDetails();
208 if (securityDetails) {
209 originState.securityDetails = securityDetails;
210 }
211
212 this._origins.set(origin, originState);
213
214 this._sidebarTree.addOrigin(origin, securityState);
215
216 // Don't construct the origin view yet (let it happen lazily).
217 }
218 }
219
220 /**
221 * @param {!WebInspector.Event} event
222 */
223 _onRequestFinished(event) {
224 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
225 this._updateFilterRequestCounts(request);
226 this._processRequest(request);
227 }
228
229 /**
230 * @param {!WebInspector.NetworkRequest} request
231 */
232 _updateFilterRequestCounts(request) {
233 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.None)
234 return;
235
236 /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */
237 var filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.All;
238 if (request.wasBlocked())
239 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blocked;
240 else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.B lockable)
241 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.BlockOver ridden;
242 else if (request.mixedContentType === NetworkAgent.RequestMixedContentType.O ptionallyBlockable)
243 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Displayed ;
244
245 if (!this._filterRequestCounts.has(filterKey))
246 this._filterRequestCounts.set(filterKey, 1);
247 else
248 this._filterRequestCounts.set(filterKey, this._filterRequestCounts.get(fil terKey) + 1);
249
250 this._mainView.refreshExplanations();
251 }
252
253 /**
254 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
255 * @return {number}
256 */
257 filterRequestCount(filterKey) {
258 return this._filterRequestCounts.get(filterKey) || 0;
259 }
260
261 showCertificateViewer() {
262 var securityModel = WebInspector.SecurityModel.fromTarget(this._target);
263 securityModel.showCertificateViewer();
264 }
265
266 /**
267 * @param {!SecurityAgent.SecurityState} stateA
268 * @param {!SecurityAgent.SecurityState} stateB
269 * @return {!SecurityAgent.SecurityState}
270 */
271 _securityStateMin(stateA, stateB) {
272 return WebInspector.SecurityModel.SecurityStateComparator(stateA, stateB) < 0 ? stateA : stateB;
273 }
274
275 /**
276 * @override
277 * @param {!WebInspector.Target} target
278 */
279 targetAdded(target) {
280 if (this._target)
281 return;
282
283 var listeners = [];
284 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target);
285 if (resourceTreeModel) {
286 listeners = listeners.concat([
287 resourceTreeModel.addEventListener(
288 WebInspector.ResourceTreeModel.Events.MainFrameNavigated, this._onMa inFrameNavigated, this),
289 resourceTreeModel.addEventListener(
290 WebInspector.ResourceTreeModel.Events.InterstitialShown, this._onInt erstitialShown, this),
291 resourceTreeModel.addEventListener(
292 WebInspector.ResourceTreeModel.Events.InterstitialHidden, this._onIn terstitialHidden, this),
293 ]);
294 }
295
296 var networkManager = WebInspector.NetworkManager.fromTarget(target);
297 if (networkManager) {
298 listeners = listeners.concat([
299 networkManager.addEventListener(
300 WebInspector.NetworkManager.Events.ResponseReceived, this._onRespons eReceived, this),
301 networkManager.addEventListener(
302 WebInspector.NetworkManager.Events.RequestFinished, this._onRequestF inished, this),
303 ]);
304 }
305
306 var securityModel = WebInspector.SecurityModel.fromTarget(target);
307 if (securityModel) {
308 listeners = listeners.concat([securityModel.addEventListener(
309 WebInspector.SecurityModel.Events.SecurityStateChanged, this._onSecuri tyStateChanged, this)]);
310 }
311
312 this._target = target;
313 this._eventListeners.set(target, listeners);
314 }
315
316 /**
317 * @override
318 * @param {!WebInspector.Target} target
319 */
320 targetRemoved(target) {
321 if (this._target !== target)
322 return;
323
324 delete this._target;
325
326 WebInspector.EventTarget.removeEventListeners(this._eventListeners.get(targe t));
327 this._eventListeners.delete(target);
328 }
329
330 /**
331 * @param {!WebInspector.Event} event
332 */
333 _onMainFrameNavigated(event) {
334 var frame = /** type {!PageAgent.Frame}*/ (event.data);
335 var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId);
336
337 this.selectAndSwitchToMainView();
338 this._sidebarTree.clearOrigins();
339 this._origins.clear();
340 this._lastResponseReceivedForLoaderId.clear();
341 this._filterRequestCounts.clear();
342 // After clearing the filtered request counts, refresh the
343 // explanations to reflect the new counts.
344 this._mainView.refreshExplanations();
345
346 if (request) {
347 var origin = WebInspector.ParsedURL.extractOrigin(request.url);
348 this._sidebarTree.setMainOrigin(origin);
349 this._processRequest(request);
350 }
351 }
352
353 _onInterstitialShown() {
354 // The panel might have been displaying the origin view on the
355 // previously loaded page. When showing an interstitial, switch
356 // back to the Overview view.
357 this.selectAndSwitchToMainView();
358 this._sidebarTree.toggleOriginsList(true /* hidden */);
359 }
360
361 _onInterstitialHidden() {
362 this._sidebarTree.toggleOriginsList(false /* hidden */);
363 }
32 }; 364 };
33 365
34 /** @typedef {string} */ 366 /** @typedef {string} */
35 WebInspector.SecurityPanel.Origin; 367 WebInspector.SecurityPanel.Origin;
36 368
37 /** 369 /**
38 * @typedef {Object} 370 * @typedef {Object}
39 * @property {!SecurityAgent.SecurityState} securityState - Current security sta te of the origin. 371 * @property {!SecurityAgent.SecurityState} securityState - Current security sta te of the origin.
40 * @property {?NetworkAgent.SecurityDetails} securityDetails - Security details of the origin, if available. 372 * @property {?NetworkAgent.SecurityDetails} securityDetails - Security details of the origin, if available.
41 * @property {?Promise<>} certificateDetailsPromise - Certificate details of the origin. 373 * @property {?Promise<>} certificateDetailsPromise - Certificate details of the origin.
42 * @property {?WebInspector.SecurityOriginView} originView - Current SecurityOri ginView corresponding to origin. 374 * @property {?WebInspector.SecurityOriginView} originView - Current SecurityOri ginView corresponding to origin.
43 */ 375 */
44 WebInspector.SecurityPanel.OriginState; 376 WebInspector.SecurityPanel.OriginState;
45 377
46 WebInspector.SecurityPanel.prototype = {
47 /**
48 * @param {!SecurityAgent.SecurityState} securityState
49 */
50 setRanInsecureContentStyle: function(securityState)
51 {
52 this._ranInsecureContentStyle = securityState;
53 },
54
55 /**
56 * @param {!SecurityAgent.SecurityState} securityState
57 */
58 setDisplayedInsecureContentStyle: function(securityState)
59 {
60 this._displayedInsecureContentStyle = securityState;
61 },
62
63 /**
64 * @param {!SecurityAgent.SecurityState} newSecurityState
65 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
66 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus
67 * @param {boolean} schemeIsCryptographic
68 */
69 _updateSecurityState: function(newSecurityState, explanations, insecureConte ntStatus, schemeIsCryptographic)
70 {
71 this._sidebarMainViewElement.setSecurityState(newSecurityState);
72 this._mainView.updateSecurityState(newSecurityState, explanations, insec ureContentStatus, schemeIsCryptographic);
73 },
74
75 /**
76 * @param {!WebInspector.Event} event
77 */
78 _onSecurityStateChanged: function(event)
79 {
80 var data = /** @type {!WebInspector.PageSecurityState} */ (event.data);
81 var securityState = /** @type {!SecurityAgent.SecurityState} */ (data.se curityState);
82 var explanations = /** @type {!Array<!SecurityAgent.SecurityStateExplana tion>} */ (data.explanations);
83 var insecureContentStatus = /** @type {?SecurityAgent.InsecureContentSta tus} */ (data.insecureContentStatus);
84 var schemeIsCryptographic = /** @type {boolean} */ (data.schemeIsCryptog raphic);
85 this._updateSecurityState(securityState, explanations, insecureContentSt atus, schemeIsCryptographic);
86 },
87
88 selectAndSwitchToMainView: function()
89 {
90 // The sidebar element will trigger displaying the main view. Rather tha n making a redundant call to display the main view, we rely on this.
91 this._sidebarMainViewElement.select();
92 },
93 /**
94 * @param {!WebInspector.SecurityPanel.Origin} origin
95 */
96 showOrigin: function(origin)
97 {
98 var originState = this._origins.get(origin);
99 if (!originState.originView)
100 originState.originView = new WebInspector.SecurityOriginView(this, o rigin, originState);
101
102 this._setVisibleView(originState.originView);
103 },
104
105 wasShown: function()
106 {
107 WebInspector.Panel.prototype.wasShown.call(this);
108 if (!this._visibleView)
109 this.selectAndSwitchToMainView();
110 },
111
112 /**
113 * @override
114 */
115 focus: function()
116 {
117 this._sidebarTree.focus();
118 },
119
120 /**
121 * @param {!WebInspector.VBox} view
122 */
123 _setVisibleView: function(view)
124 {
125 if (this._visibleView === view)
126 return;
127
128 if (this._visibleView)
129 this._visibleView.detach();
130
131 this._visibleView = view;
132
133 if (view)
134 this.splitWidget().setMainWidget(view);
135 },
136
137 /**
138 * @param {!WebInspector.Event} event
139 */
140 _onResponseReceived: function(event)
141 {
142 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
143 if (request.resourceType() === WebInspector.resourceTypes.Document)
144 this._lastResponseReceivedForLoaderId.set(request.loaderId, request) ;
145 },
146
147 /**
148 * @param {!WebInspector.NetworkRequest} request
149 */
150 _processRequest: function(request)
151 {
152 var origin = WebInspector.ParsedURL.extractOrigin(request.url);
153
154 if (!origin) {
155 // We don't handle resources like data: URIs. Most of them don't aff ect the lock icon.
156 return;
157 }
158
159 var securityState = /** @type {!SecurityAgent.SecurityState} */ (request .securityState());
160
161 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.Bl ockable && this._ranInsecureContentStyle)
162 securityState = this._ranInsecureContentStyle;
163 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy pe.OptionallyBlockable && this._displayedInsecureContentStyle)
164 securityState = this._displayedInsecureContentStyle;
165
166 if (this._origins.has(origin)) {
167 var originState = this._origins.get(origin);
168 var oldSecurityState = originState.securityState;
169 originState.securityState = this._securityStateMin(oldSecurityState, securityState);
170 if (oldSecurityState !== originState.securityState) {
171 this._sidebarTree.updateOrigin(origin, securityState);
172 if (originState.originView)
173 originState.originView.setSecurityState(securityState);
174 }
175 } else {
176 // TODO(lgarron): Store a (deduplicated) list of different security details we have seen. https://crbug.com/503170
177 var originState = {};
178 originState.securityState = securityState;
179
180 var securityDetails = request.securityDetails();
181 if (securityDetails) {
182 originState.securityDetails = securityDetails;
183 }
184
185 this._origins.set(origin, originState);
186
187 this._sidebarTree.addOrigin(origin, securityState);
188
189 // Don't construct the origin view yet (let it happen lazily).
190 }
191 },
192
193 /**
194 * @param {!WebInspector.Event} event
195 */
196 _onRequestFinished: function(event)
197 {
198 var request = /** @type {!WebInspector.NetworkRequest} */ (event.data);
199 this._updateFilterRequestCounts(request);
200 this._processRequest(request);
201 },
202
203 /**
204 * @param {!WebInspector.NetworkRequest} request
205 */
206 _updateFilterRequestCounts: function(request)
207 {
208 if (request.mixedContentType === NetworkAgent.RequestMixedContentType.No ne)
209 return;
210
211 /** @type {!WebInspector.NetworkLogView.MixedContentFilterValues} */
212 var filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.All ;
213 if (request.wasBlocked())
214 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blo cked;
215 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy pe.Blockable)
216 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Blo ckOverridden;
217 else if (request.mixedContentType === NetworkAgent.RequestMixedContentTy pe.OptionallyBlockable)
218 filterKey = WebInspector.NetworkLogView.MixedContentFilterValues.Dis played;
219
220 if (!this._filterRequestCounts.has(filterKey))
221 this._filterRequestCounts.set(filterKey, 1);
222 else
223 this._filterRequestCounts.set(filterKey, this._filterRequestCounts.g et(filterKey) + 1);
224
225 this._mainView.refreshExplanations();
226 },
227
228 /**
229 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
230 * @return {number}
231 */
232 filterRequestCount: function(filterKey)
233 {
234 return this._filterRequestCounts.get(filterKey) || 0;
235 },
236
237 showCertificateViewer: function()
238 {
239 var securityModel = WebInspector.SecurityModel.fromTarget(this._target);
240 securityModel.showCertificateViewer();
241 },
242
243 /**
244 * @param {!SecurityAgent.SecurityState} stateA
245 * @param {!SecurityAgent.SecurityState} stateB
246 * @return {!SecurityAgent.SecurityState}
247 */
248 _securityStateMin: function(stateA, stateB)
249 {
250 return WebInspector.SecurityModel.SecurityStateComparator(stateA, stateB ) < 0 ? stateA : stateB;
251 },
252
253 /**
254 * @override
255 * @param {!WebInspector.Target} target
256 */
257 targetAdded: function(target)
258 {
259 if (this._target)
260 return;
261
262 var listeners = [];
263 var resourceTreeModel = WebInspector.ResourceTreeModel.fromTarget(target );
264 if (resourceTreeModel) {
265 listeners = listeners.concat([
266 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.MainFrameNavigated, this._onMainFrameNavigated, this),
267 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.InterstitialShown, this._onInterstitialShown, this),
268 resourceTreeModel.addEventListener(WebInspector.ResourceTreeMode l.Events.InterstitialHidden, this._onInterstitialHidden, this),
269 ]);
270 }
271
272 var networkManager = WebInspector.NetworkManager.fromTarget(target);
273 if (networkManager) {
274 listeners = listeners.concat([
275 networkManager.addEventListener(WebInspector.NetworkManager.Even ts.ResponseReceived, this._onResponseReceived, this),
276 networkManager.addEventListener(WebInspector.NetworkManager.Even ts.RequestFinished, this._onRequestFinished, this),
277 ]);
278 }
279
280 var securityModel = WebInspector.SecurityModel.fromTarget(target);
281 if (securityModel) {
282 listeners = listeners.concat([
283 securityModel.addEventListener(WebInspector.SecurityModel.Events .SecurityStateChanged, this._onSecurityStateChanged, this)
284 ]);
285 }
286
287 this._target = target;
288 this._eventListeners.set(target, listeners);
289 },
290
291 /**
292 * @override
293 * @param {!WebInspector.Target} target
294 */
295 targetRemoved: function(target)
296 {
297 if (this._target !== target)
298 return;
299
300 delete this._target;
301
302 WebInspector.EventTarget.removeEventListeners(this._eventListeners.get(t arget));
303 this._eventListeners.delete(target);
304 },
305
306 /**
307 * @param {!WebInspector.Event} event
308 */
309 _onMainFrameNavigated: function(event)
310 {
311 var frame = /** type {!PageAgent.Frame}*/ (event.data);
312 var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId);
313
314 this.selectAndSwitchToMainView();
315 this._sidebarTree.clearOrigins();
316 this._origins.clear();
317 this._lastResponseReceivedForLoaderId.clear();
318 this._filterRequestCounts.clear();
319 // After clearing the filtered request counts, refresh the
320 // explanations to reflect the new counts.
321 this._mainView.refreshExplanations();
322
323 if (request) {
324 var origin = WebInspector.ParsedURL.extractOrigin(request.url);
325 this._sidebarTree.setMainOrigin(origin);
326 this._processRequest(request);
327 }
328 },
329
330 _onInterstitialShown: function()
331 {
332 // The panel might have been displaying the origin view on the
333 // previously loaded page. When showing an interstitial, switch
334 // back to the Overview view.
335 this.selectAndSwitchToMainView();
336 this._sidebarTree.toggleOriginsList(true /* hidden */);
337 },
338
339 _onInterstitialHidden: function()
340 {
341 this._sidebarTree.toggleOriginsList(false /* hidden */);
342 },
343
344 __proto__: WebInspector.PanelWithSidebar.prototype
345 };
346 378
347 /** 379 /**
348 * @return {!WebInspector.SecurityPanel} 380 * @unrestricted
349 */ 381 */
350 WebInspector.SecurityPanel._instance = function() 382 WebInspector.SecurityPanelSidebarTree = class extends TreeOutlineInShadow {
351 { 383 /**
352 return /** @type {!WebInspector.SecurityPanel} */ (self.runtime.sharedInstan ce(WebInspector.SecurityPanel)); 384 * @param {!WebInspector.SecurityPanelSidebarTreeElement} mainViewElement
353 }; 385 * @param {function(!WebInspector.SecurityPanel.Origin)} showOriginInPanel
354 386 */
355 /** 387 constructor(mainViewElement, showOriginInPanel) {
356 * @param {string} text 388 super();
357 * @param {!WebInspector.SecurityPanel} panel 389 this.registerRequiredCSS('security/sidebar.css');
358 * @return {!Element} 390 this.registerRequiredCSS('security/lockIcon.css');
359 */
360 WebInspector.SecurityPanel.createCertificateViewerButton = function(text, panel)
361 {
362 /**
363 * @param {!Event} e
364 */
365 function showCertificateViewer(e)
366 {
367 e.consume();
368 panel.showCertificateViewer();
369 }
370
371 return createTextButton(text, showCertificateViewer, "security-certificate-b utton");
372 };
373
374 /**
375 * @param {string} text
376 * @param {string} origin
377 * @return {!Element}
378 */
379 WebInspector.SecurityPanel.createCertificateViewerButton2 = function(text, origi n)
380 {
381 /**
382 * @param {!Event} e
383 */
384 function showCertificateViewer(e)
385 {
386 function certificateCallback(names)
387 {
388 InspectorFrontendHost.showCertificateViewer(names);
389 }
390
391 e.consume();
392 WebInspector.multitargetNetworkManager.getCertificate(origin, certificat eCallback);
393 }
394
395 return createTextButton(text, showCertificateViewer, "security-certificate-b utton");
396 };
397
398 /**
399 * @constructor
400 * @extends {TreeOutlineInShadow}
401 * @param {!WebInspector.SecurityPanelSidebarTreeElement} mainViewElement
402 * @param {function(!WebInspector.SecurityPanel.Origin)} showOriginInPanel
403 */
404 WebInspector.SecurityPanelSidebarTree = function(mainViewElement, showOriginInPa nel)
405 {
406 TreeOutlineInShadow.call(this);
407 this.registerRequiredCSS("security/sidebar.css");
408 this.registerRequiredCSS("security/lockIcon.css");
409 this.appendChild(mainViewElement); 391 this.appendChild(mainViewElement);
410 392
411 this._showOriginInPanel = showOriginInPanel; 393 this._showOriginInPanel = showOriginInPanel;
412 this._mainOrigin = null; 394 this._mainOrigin = null;
413 395
414 /** @type {!Map<!WebInspector.SecurityPanelSidebarTree.OriginGroupName, !Tre eElement>} */ 396 /** @type {!Map<!WebInspector.SecurityPanelSidebarTree.OriginGroupName, !Tre eElement>} */
415 this._originGroups = new Map(); 397 this._originGroups = new Map();
416 398
417 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { 399 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) {
418 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupN ame[key]; 400 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupNam e[key];
419 var originGroup = new TreeElement(originGroupName, true); 401 var originGroup = new TreeElement(originGroupName, true);
420 originGroup.selectable = false; 402 originGroup.selectable = false;
421 originGroup.expand(); 403 originGroup.expand();
422 originGroup.listItemElement.classList.add("security-sidebar-origins"); 404 originGroup.listItemElement.classList.add('security-sidebar-origins');
423 this._originGroups.set(originGroupName, originGroup); 405 this._originGroups.set(originGroupName, originGroup);
424 this.appendChild(originGroup); 406 this.appendChild(originGroup);
425 } 407 }
426 this._clearOriginGroups(); 408 this._clearOriginGroups();
427 409
428 // This message will be removed by clearOrigins() during the first new page load after the panel was opened. 410 // This message will be removed by clearOrigins() during the first new page load after the panel was opened.
429 var mainViewReloadMessage = new TreeElement(WebInspector.UIString("Reload to view details")); 411 var mainViewReloadMessage = new TreeElement(WebInspector.UIString('Reload to view details'));
430 mainViewReloadMessage.selectable = false; 412 mainViewReloadMessage.selectable = false;
431 mainViewReloadMessage.listItemElement.classList.add("security-main-view-relo ad-message"); 413 mainViewReloadMessage.listItemElement.classList.add('security-main-view-relo ad-message');
432 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName .MainOrigin).appendChild(mainViewReloadMessage); 414 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName .MainOrigin)
415 .appendChild(mainViewReloadMessage);
433 416
434 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa nelSidebarTreeElement>} */ 417 /** @type {!Map<!WebInspector.SecurityPanel.Origin, !WebInspector.SecurityPa nelSidebarTreeElement>} */
435 this._elementsByOrigin = new Map(); 418 this._elementsByOrigin = new Map();
419 }
420
421 /**
422 * @param {boolean} hidden
423 */
424 toggleOriginsList(hidden) {
425 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) {
426 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupNam e[key];
427 var group = this._originGroups.get(originGroupName);
428 if (group)
429 group.hidden = hidden;
430 }
431 }
432
433 /**
434 * @param {!WebInspector.SecurityPanel.Origin} origin
435 * @param {!SecurityAgent.SecurityState} securityState
436 */
437 addOrigin(origin, securityState) {
438 var originElement = new WebInspector.SecurityPanelSidebarTreeElement(
439 origin, this._showOriginInPanel.bind(this, origin), 'security-sidebar-tr ee-item', 'security-property');
440 originElement.listItemElement.title = origin;
441 this._elementsByOrigin.set(origin, originElement);
442 this.updateOrigin(origin, securityState);
443 }
444
445 /**
446 * @param {!WebInspector.SecurityPanel.Origin} origin
447 */
448 setMainOrigin(origin) {
449 this._mainOrigin = origin;
450 }
451
452 /**
453 * @param {!WebInspector.SecurityPanel.Origin} origin
454 * @param {!SecurityAgent.SecurityState} securityState
455 */
456 updateOrigin(origin, securityState) {
457 var originElement =
458 /** @type {!WebInspector.SecurityPanelSidebarTreeElement} */ (this._elem entsByOrigin.get(origin));
459 originElement.setSecurityState(securityState);
460
461 var newParent;
462 if (origin === this._mainOrigin) {
463 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTree.O riginGroupName.MainOrigin);
464 } else {
465 switch (securityState) {
466 case SecurityAgent.SecurityState.Secure:
467 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr ee.OriginGroupName.Secure);
468 break;
469 case SecurityAgent.SecurityState.Unknown:
470 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr ee.OriginGroupName.Unknown);
471 break;
472 default:
473 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebarTr ee.OriginGroupName.NonSecure);
474 break;
475 }
476 }
477
478 var oldParent = originElement.parent;
479 if (oldParent !== newParent) {
480 if (oldParent) {
481 oldParent.removeChild(originElement);
482 if (oldParent.childCount() === 0)
483 oldParent.hidden = true;
484 }
485 newParent.appendChild(originElement);
486 newParent.hidden = false;
487 }
488 }
489
490 _clearOriginGroups() {
491 for (var originGroup of this._originGroups.values()) {
492 originGroup.removeChildren();
493 originGroup.hidden = true;
494 }
495 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroupName .MainOrigin).hidden = false;
496 }
497
498 clearOrigins() {
499 this._clearOriginGroups();
500 this._elementsByOrigin.clear();
501 }
436 }; 502 };
437 503
438 WebInspector.SecurityPanelSidebarTree.prototype = {
439 /**
440 * @param {boolean} hidden
441 */
442 toggleOriginsList: function(hidden)
443 {
444 for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) {
445 var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGr oupName[key];
446 var group = this._originGroups.get(originGroupName);
447 if (group)
448 group.hidden = hidden;
449 }
450 },
451
452 /**
453 * @param {!WebInspector.SecurityPanel.Origin} origin
454 * @param {!SecurityAgent.SecurityState} securityState
455 */
456 addOrigin: function(origin, securityState)
457 {
458 var originElement = new WebInspector.SecurityPanelSidebarTreeElement(ori gin, this._showOriginInPanel.bind(this, origin), "security-sidebar-tree-item", " security-property");
459 originElement.listItemElement.title = origin;
460 this._elementsByOrigin.set(origin, originElement);
461 this.updateOrigin(origin, securityState);
462 },
463
464 /**
465 * @param {!WebInspector.SecurityPanel.Origin} origin
466 */
467 setMainOrigin: function(origin)
468 {
469 this._mainOrigin = origin;
470 },
471
472 /**
473 * @param {!WebInspector.SecurityPanel.Origin} origin
474 * @param {!SecurityAgent.SecurityState} securityState
475 */
476 updateOrigin: function(origin, securityState)
477 {
478 var originElement = /** @type {!WebInspector.SecurityPanelSidebarTreeEle ment} */ (this._elementsByOrigin.get(origin));
479 originElement.setSecurityState(securityState);
480
481 var newParent;
482 if (origin === this._mainOrigin) {
483 newParent = this._originGroups.get(WebInspector.SecurityPanelSidebar Tree.OriginGroupName.MainOrigin);
484 } else {
485 switch (securityState) {
486 case SecurityAgent.SecurityState.Secure:
487 newParent = this._originGroups.get(WebInspector.SecurityPanelSid ebarTree.OriginGroupName.Secure);
488 break;
489 case SecurityAgent.SecurityState.Unknown:
490 newParent = this._originGroups.get(WebInspector.SecurityPanelSid ebarTree.OriginGroupName.Unknown);
491 break;
492 default:
493 newParent = this._originGroups.get(WebInspector.SecurityPanelSid ebarTree.OriginGroupName.NonSecure);
494 break;
495 }
496 }
497
498 var oldParent = originElement.parent;
499 if (oldParent !== newParent) {
500 if (oldParent) {
501 oldParent.removeChild(originElement);
502 if (oldParent.childCount() === 0)
503 oldParent.hidden = true;
504 }
505 newParent.appendChild(originElement);
506 newParent.hidden = false;
507 }
508
509 },
510
511 _clearOriginGroups: function()
512 {
513 for (var originGroup of this._originGroups.values()) {
514 originGroup.removeChildren();
515 originGroup.hidden = true;
516 }
517 this._originGroups.get(WebInspector.SecurityPanelSidebarTree.OriginGroup Name.MainOrigin).hidden = false;
518 },
519
520 clearOrigins: function()
521 {
522 this._clearOriginGroups();
523 this._elementsByOrigin.clear();
524 },
525
526 __proto__: TreeOutlineInShadow.prototype
527 };
528
529
530 /** 504 /**
531 * A mapping from Javascript key IDs to names (sidebar section titles). 505 * A mapping from Javascript key IDs to names (sidebar section titles).
532 * Note: The names are used as keys into a map, so they must be distinct from ea ch other. 506 * Note: The names are used as keys into a map, so they must be distinct from ea ch other.
533 * @enum {string} 507 * @enum {string}
534 */ 508 */
535 WebInspector.SecurityPanelSidebarTree.OriginGroupName = { 509 WebInspector.SecurityPanelSidebarTree.OriginGroupName = {
536 MainOrigin: WebInspector.UIString("Main Origin"), 510 MainOrigin: WebInspector.UIString('Main Origin'),
537 NonSecure: WebInspector.UIString("Non-Secure Origins"), 511 NonSecure: WebInspector.UIString('Non-Secure Origins'),
538 Secure: WebInspector.UIString("Secure Origins"), 512 Secure: WebInspector.UIString('Secure Origins'),
539 Unknown: WebInspector.UIString("Unknown / Canceled") 513 Unknown: WebInspector.UIString('Unknown / Canceled')
540 }; 514 };
541 515
542
543 /** 516 /**
544 * @constructor 517 * @unrestricted
545 * @extends {TreeElement}
546 * @param {string} text
547 * @param {function()} selectCallback
548 * @param {string} className
549 * @param {string} cssPrefix
550 */ 518 */
551 WebInspector.SecurityPanelSidebarTreeElement = function(text, selectCallback, cl assName, cssPrefix) 519 WebInspector.SecurityPanelSidebarTreeElement = class extends TreeElement {
552 { 520 /**
553 TreeElement.call(this, "", false); 521 * @param {string} text
522 * @param {function()} selectCallback
523 * @param {string} className
524 * @param {string} cssPrefix
525 */
526 constructor(text, selectCallback, className, cssPrefix) {
527 super('', false);
554 this._selectCallback = selectCallback; 528 this._selectCallback = selectCallback;
555 this._cssPrefix = cssPrefix; 529 this._cssPrefix = cssPrefix;
556 this.listItemElement.classList.add(className); 530 this.listItemElement.classList.add(className);
557 this._iconElement = this.listItemElement.createChild("div", "icon"); 531 this._iconElement = this.listItemElement.createChild('div', 'icon');
558 this._iconElement.classList.add(this._cssPrefix); 532 this._iconElement.classList.add(this._cssPrefix);
559 this.listItemElement.createChild("span", "title").textContent = text; 533 this.listItemElement.createChild('span', 'title').textContent = text;
560 this.setSecurityState(SecurityAgent.SecurityState.Unknown); 534 this.setSecurityState(SecurityAgent.SecurityState.Unknown);
535 }
536
537 /**
538 * @param {!WebInspector.SecurityPanelSidebarTreeElement} a
539 * @param {!WebInspector.SecurityPanelSidebarTreeElement} b
540 * @return {number}
541 */
542 static SecurityStateComparator(a, b) {
543 return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(), b.securityState());
544 }
545
546 /**
547 * @param {!SecurityAgent.SecurityState} newSecurityState
548 */
549 setSecurityState(newSecurityState) {
550 if (this._securityState)
551 this._iconElement.classList.remove(this._cssPrefix + '-' + this._securityS tate);
552
553 this._securityState = newSecurityState;
554 this._iconElement.classList.add(this._cssPrefix + '-' + newSecurityState);
555 }
556
557 /**
558 * @return {!SecurityAgent.SecurityState}
559 */
560 securityState() {
561 return this._securityState;
562 }
563
564 /**
565 * @override
566 * @return {boolean}
567 */
568 onselect() {
569 this._selectCallback();
570 return true;
571 }
561 }; 572 };
562 573
563 WebInspector.SecurityPanelSidebarTreeElement.prototype = { 574
575 /**
576 * @unrestricted
577 */
578 WebInspector.SecurityMainView = class extends WebInspector.VBox {
579 /**
580 * @param {!WebInspector.SecurityPanel} panel
581 */
582 constructor(panel) {
583 super(true);
584 this.registerRequiredCSS('security/mainView.css');
585 this.registerRequiredCSS('security/lockIcon.css');
586 this.setMinimumSize(200, 100);
587
588 this.contentElement.classList.add('security-main-view');
589
590 this._panel = panel;
591
592 this._summarySection = this.contentElement.createChild('div', 'security-summ ary');
593
594 // Info explanations should appear after all others.
595 this._securityExplanationsMain = this.contentElement.createChild('div', 'sec urity-explanation-list');
596 this._securityExplanationsExtra =
597 this.contentElement.createChild('div', 'security-explanation-list securi ty-explanations-extra');
598
599 // Fill the security summary section.
600 this._summarySection.createChild('div', 'security-summary-section-title').te xtContent =
601 WebInspector.UIString('Security Overview');
602
603 var lockSpectrum = this._summarySection.createChild('div', 'lock-spectrum');
604 lockSpectrum.createChild('div', 'lock-icon lock-icon-secure').title = WebIns pector.UIString('Secure');
605 lockSpectrum.createChild('div', 'lock-icon lock-icon-neutral').title = WebIn spector.UIString('Not Secure');
606 lockSpectrum.createChild('div', 'lock-icon lock-icon-insecure').title =
607 WebInspector.UIString('Not Secure (Broken)');
608
609 this._summarySection.createChild('div', 'triangle-pointer-container')
610 .createChild('div', 'triangle-pointer-wrapper')
611 .createChild('div', 'triangle-pointer');
612
613 this._summaryText = this._summarySection.createChild('div', 'security-summar y-text');
614 }
615
616 /**
617 * @param {!Element} parent
618 * @param {!SecurityAgent.SecurityStateExplanation} explanation
619 * @return {!Element}
620 */
621 _addExplanation(parent, explanation) {
622 var explanationSection = parent.createChild('div', 'security-explanation');
623 explanationSection.classList.add('security-explanation-' + explanation.secur ityState);
624
625 explanationSection.createChild('div', 'security-property')
626 .classList.add('security-property-' + explanation.securityState);
627 var text = explanationSection.createChild('div', 'security-explanation-text' );
628 text.createChild('div', 'security-explanation-title').textContent = explanat ion.summary;
629 text.createChild('div').textContent = explanation.description;
630
631 if (explanation.hasCertificate) {
632 text.appendChild(WebInspector.SecurityPanel.createCertificateViewerButton(
633 WebInspector.UIString('View certificate'), this._panel));
634 }
635
636 return text;
637 }
638
639 /**
640 * @param {!SecurityAgent.SecurityState} newSecurityState
641 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
642 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus
643 * @param {boolean} schemeIsCryptographic
644 */
645 updateSecurityState(newSecurityState, explanations, insecureContentStatus, sch emeIsCryptographic) {
646 // Remove old state.
647 // It's safe to call this even when this._securityState is undefined.
648 this._summarySection.classList.remove('security-summary-' + this._securitySt ate);
649
650 // Add new state.
651 this._securityState = newSecurityState;
652 this._summarySection.classList.add('security-summary-' + this._securityState );
653 var summaryExplanationStrings = {
654 'unknown': WebInspector.UIString('The security of this page is unknown.'),
655 'insecure': WebInspector.UIString('This page is not secure (broken HTTPS). '),
656 'neutral': WebInspector.UIString('This page is not secure.'),
657 'secure': WebInspector.UIString('This page is secure (valid HTTPS).')
658 };
659 this._summaryText.textContent = summaryExplanationStrings[this._securityStat e];
660
661 this._explanations = explanations, this._insecureContentStatus = insecureCon tentStatus;
662 this._schemeIsCryptographic = schemeIsCryptographic;
663
664 this._panel.setRanInsecureContentStyle(insecureContentStatus.ranInsecureCont entStyle);
665 this._panel.setDisplayedInsecureContentStyle(insecureContentStatus.displayed InsecureContentStyle);
666
667 this.refreshExplanations();
668 }
669
670 refreshExplanations() {
671 this._securityExplanationsMain.removeChildren();
672 this._securityExplanationsExtra.removeChildren();
673 for (var explanation of this._explanations) {
674 if (explanation.securityState === SecurityAgent.SecurityState.Info) {
675 this._addExplanation(this._securityExplanationsExtra, explanation);
676 } else {
677 this._addExplanation(this._securityExplanationsMain, explanation);
678 }
679 }
680
681 this._addMixedContentExplanations();
682 this._addContentWithCertErrorsExplanations();
683
684 // If all resources were served securely, add a Secure explanation.
685 if (this._schemeIsCryptographic && this._insecureContentStatus &&
686 (!this._insecureContentStatus.displayedMixedContent && !this._insecureCo ntentStatus.ranMixedContent &&
687 !this._insecureContentStatus.displayedContentWithCertErrors &&
688 !this._insecureContentStatus.ranContentWithCertErrors)) {
689 this._addExplanation(this._securityExplanationsMain, /** @type {!SecurityA gent.SecurityStateExplanation} */ ({
690 'securityState': SecurityAgent.SecurityState.Secure ,
691 'summary': WebInspector.UIString('Secure Resources' ),
692 'description': WebInspector.UIString('All resources on this page are served securely.')
693 }));
694 }
695 }
696
697 _addMixedContentExplanations() {
698 if (!this._schemeIsCryptographic)
699 return;
700
701 if (this._insecureContentStatus &&
702 (this._insecureContentStatus.ranMixedContent || this._insecureContentSta tus.displayedMixedContent)) {
703 if (this._insecureContentStatus.ranMixedContent)
704 this._addMixedContentExplanation(
705 this._securityExplanationsMain, this._insecureContentStatus.ranInsec ureContentStyle,
706 WebInspector.UIString('Active Mixed Content'),
707 WebInspector.UIString(
708 'You have recently allowed non-secure content (such as scripts o r iframes) to run on this site.'),
709 WebInspector.NetworkLogView.MixedContentFilterValues.BlockOverridden ,
710 showBlockOverriddenMixedContentInNetworkPanel);
711 if (this._insecureContentStatus.displayedMixedContent)
712 this._addMixedContentExplanation(
713 this._securityExplanationsMain, this._insecureContentStatus.displaye dInsecureContentStyle,
714 WebInspector.UIString('Mixed Content'), WebInspector.UIString('The s ite includes HTTP resources.'),
715 WebInspector.NetworkLogView.MixedContentFilterValues.Displayed, show DisplayedMixedContentInNetworkPanel);
716 }
717
718 if (this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedContentF ilterValues.Blocked) > 0)
719 this._addMixedContentExplanation(
720 this._securityExplanationsExtra, SecurityAgent.SecurityState.Info,
721 WebInspector.UIString('Blocked mixed content'),
722 WebInspector.UIString('Your page requested non-secure resources that w ere blocked.'),
723 WebInspector.NetworkLogView.MixedContentFilterValues.Blocked, showBloc kedMixedContentInNetworkPanel);
724
564 /** 725 /**
565 * @param {!SecurityAgent.SecurityState} newSecurityState 726 * @param {!Event} e
566 */ 727 */
567 setSecurityState: function(newSecurityState) 728 function showDisplayedMixedContentInNetworkPanel(e) {
568 { 729 e.consume();
569 if (this._securityState) 730 WebInspector.NetworkPanel.revealAndFilter([{
570 this._iconElement.classList.remove(this._cssPrefix + "-" + this._sec urityState); 731 filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
571 732 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Displa yed
572 this._securityState = newSecurityState; 733 }]);
573 this._iconElement.classList.add(this._cssPrefix + "-" + newSecurityState ); 734 }
574 },
575 735
576 /** 736 /**
577 * @return {!SecurityAgent.SecurityState} 737 * @param {!Event} e
578 */ 738 */
579 securityState: function() 739 function showBlockOverriddenMixedContentInNetworkPanel(e) {
580 { 740 e.consume();
581 return this._securityState; 741 WebInspector.NetworkPanel.revealAndFilter([{
582 }, 742 filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
743 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.BlockO verridden
744 }]);
745 }
583 746
584 /** 747 /**
585 * @override 748 * @param {!Event} e
586 * @return {boolean}
587 */ 749 */
588 onselect: function() 750 function showBlockedMixedContentInNetworkPanel(e) {
589 { 751 e.consume();
590 this._selectCallback(); 752 WebInspector.NetworkPanel.revealAndFilter([{
591 return true; 753 filterType: WebInspector.NetworkLogView.FilterType.MixedContent,
592 }, 754 filterValue: WebInspector.NetworkLogView.MixedContentFilterValues.Blocke d
593 755 }]);
594 __proto__: TreeElement.prototype 756 }
757 }
758
759 /**
760 * @param {!Element} parent
761 * @param {!SecurityAgent.SecurityState} securityState
762 * @param {string} summary
763 * @param {string} description
764 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
765 * @param {!Function} networkFilterFn
766 */
767 _addMixedContentExplanation(parent, securityState, summary, description, filte rKey, networkFilterFn) {
768 var mixedContentExplanation = /** @type {!SecurityAgent.SecurityStateExplana tion} */ (
769 {'securityState': securityState, 'summary': summary, 'description': desc ription});
770
771 var explanation = this._addExplanation(parent, mixedContentExplanation);
772
773 var filterRequestCount = this._panel.filterRequestCount(filterKey);
774 if (!filterRequestCount) {
775 // Network instrumentation might not have been enabled for the page
776 // load, so the security panel does not necessarily know a count of
777 // individual mixed requests at this point. Prompt them to refresh
778 // instead of pointing them to the Network panel to get prompted
779 // to refresh.
780 var refreshPrompt = explanation.createChild('div', 'security-mixed-content ');
781 refreshPrompt.textContent = WebInspector.UIString('Reload the page to reco rd requests for HTTP resources.');
782 return;
783 }
784
785 var requestsAnchor = explanation.createChild('div', 'security-mixed-content link');
786 if (filterRequestCount === 1) {
787 requestsAnchor.textContent = WebInspector.UIString('View %d request in Net work Panel', filterRequestCount);
788 } else {
789 requestsAnchor.textContent = WebInspector.UIString('View %d requests in Ne twork Panel', filterRequestCount);
790 }
791 requestsAnchor.href = '';
792 requestsAnchor.addEventListener('click', networkFilterFn);
793 }
794
795 _addContentWithCertErrorsExplanations() {
796 if (!this._schemeIsCryptographic)
797 return;
798
799 if (!this._insecureContentStatus)
800 return;
801
802 if (this._insecureContentStatus.ranContentWithCertErrors) {
803 this._addExplanation(
804 this._securityExplanationsMain, /** @type {!SecurityAgent.SecurityStat eExplanation} */ ({
805 'securityState': this._insecureContentStatus.ranInsecureContentStyle ,
806 'summary': WebInspector.UIString('Active content with certificate er rors'),
807 'description': WebInspector.UIString(
808 'You have recently allowed content loaded with certificate error s (such as scripts or iframes) to run on this site.')
809 }));
810 }
811
812 if (this._insecureContentStatus.displayedContentWithCertErrors) {
813 this._addExplanation(this._securityExplanationsMain, /** @type {!SecurityA gent.SecurityStateExplanation} */ ({
814 'securityState': this._insecureContentStatus.displa yedInsecureContentStyle,
815 'summary': WebInspector.UIString('Content with cert ificate errors'),
816 'description': WebInspector.UIString(
817 'This site includes resources that were loaded with certificate errors.')
818 }));
819 }
820 }
595 }; 821 };
596 822
597 /** 823 /**
598 * @param {!WebInspector.SecurityPanelSidebarTreeElement} a 824 * @unrestricted
599 * @param {!WebInspector.SecurityPanelSidebarTreeElement} b
600 * @return {number}
601 */ 825 */
602 WebInspector.SecurityPanelSidebarTreeElement.SecurityStateComparator = function( a, b) 826 WebInspector.SecurityOriginView = class extends WebInspector.VBox {
603 { 827 /**
604 return WebInspector.SecurityModel.SecurityStateComparator(a.securityState(), b.securityState()); 828 * @param {!WebInspector.SecurityPanel} panel
605 }; 829 * @param {!WebInspector.SecurityPanel.Origin} origin
606 830 * @param {!WebInspector.SecurityPanel.OriginState} originState
607 /** 831 */
608 * @constructor 832 constructor(panel, origin, originState) {
609 * @extends {WebInspector.VBox} 833 super();
610 * @param {!WebInspector.SecurityPanel} panel
611 */
612 WebInspector.SecurityMainView = function(panel)
613 {
614 WebInspector.VBox.call(this, true);
615 this.registerRequiredCSS("security/mainView.css");
616 this.registerRequiredCSS("security/lockIcon.css");
617 this.setMinimumSize(200, 100);
618
619 this.contentElement.classList.add("security-main-view");
620
621 this._panel = panel;
622
623 this._summarySection = this.contentElement.createChild("div", "security-summ ary");
624
625 // Info explanations should appear after all others.
626 this._securityExplanationsMain = this.contentElement.createChild("div", "sec urity-explanation-list");
627 this._securityExplanationsExtra = this.contentElement.createChild("div", "se curity-explanation-list security-explanations-extra");
628
629 // Fill the security summary section.
630 this._summarySection.createChild("div", "security-summary-section-title").te xtContent = WebInspector.UIString("Security Overview");
631
632 var lockSpectrum = this._summarySection.createChild("div", "lock-spectrum");
633 lockSpectrum.createChild("div", "lock-icon lock-icon-secure").title = WebIns pector.UIString("Secure");
634 lockSpectrum.createChild("div", "lock-icon lock-icon-neutral").title = WebIn spector.UIString("Not Secure");
635 lockSpectrum.createChild("div", "lock-icon lock-icon-insecure").title = WebI nspector.UIString("Not Secure (Broken)");
636
637 this._summarySection.createChild("div", "triangle-pointer-container").create Child("div", "triangle-pointer-wrapper").createChild("div", "triangle-pointer");
638
639 this._summaryText = this._summarySection.createChild("div", "security-summar y-text");
640 };
641
642 WebInspector.SecurityMainView.prototype = {
643 /**
644 * @param {!Element} parent
645 * @param {!SecurityAgent.SecurityStateExplanation} explanation
646 * @return {!Element}
647 */
648 _addExplanation: function(parent, explanation)
649 {
650 var explanationSection = parent.createChild("div", "security-explanation ");
651 explanationSection.classList.add("security-explanation-" + explanation.s ecurityState);
652
653 explanationSection.createChild("div", "security-property").classList.add ("security-property-" + explanation.securityState);
654 var text = explanationSection.createChild("div", "security-explanation-t ext");
655 text.createChild("div", "security-explanation-title").textContent = expl anation.summary;
656 text.createChild("div").textContent = explanation.description;
657
658 if (explanation.hasCertificate) {
659 text.appendChild(WebInspector.SecurityPanel.createCertificateViewerB utton(WebInspector.UIString("View certificate"), this._panel));
660 }
661
662 return text;
663 },
664
665 /**
666 * @param {!SecurityAgent.SecurityState} newSecurityState
667 * @param {!Array<!SecurityAgent.SecurityStateExplanation>} explanations
668 * @param {?SecurityAgent.InsecureContentStatus} insecureContentStatus
669 * @param {boolean} schemeIsCryptographic
670 */
671 updateSecurityState: function(newSecurityState, explanations, insecureConten tStatus, schemeIsCryptographic)
672 {
673 // Remove old state.
674 // It's safe to call this even when this._securityState is undefined.
675 this._summarySection.classList.remove("security-summary-" + this._securi tyState);
676
677 // Add new state.
678 this._securityState = newSecurityState;
679 this._summarySection.classList.add("security-summary-" + this._securityS tate);
680 var summaryExplanationStrings = {
681 "unknown": WebInspector.UIString("The security of this page is unkn own."),
682 "insecure": WebInspector.UIString("This page is not secure (broken H TTPS)."),
683 "neutral": WebInspector.UIString("This page is not secure."),
684 "secure": WebInspector.UIString("This page is secure (valid HTTPS) .")
685 };
686 this._summaryText.textContent = summaryExplanationStrings[this._security State];
687
688 this._explanations = explanations,
689 this._insecureContentStatus = insecureContentStatus;
690 this._schemeIsCryptographic = schemeIsCryptographic;
691
692 this._panel.setRanInsecureContentStyle(insecureContentStatus.ranInsecure ContentStyle);
693 this._panel.setDisplayedInsecureContentStyle(insecureContentStatus.displ ayedInsecureContentStyle);
694
695 this.refreshExplanations();
696 },
697
698 refreshExplanations: function()
699 {
700 this._securityExplanationsMain.removeChildren();
701 this._securityExplanationsExtra.removeChildren();
702 for (var explanation of this._explanations) {
703 if (explanation.securityState === SecurityAgent.SecurityState.Info) {
704 this._addExplanation(this._securityExplanationsExtra, explanatio n);
705 } else {
706 this._addExplanation(this._securityExplanationsMain, explanation );
707 }
708 }
709
710 this._addMixedContentExplanations();
711 this._addContentWithCertErrorsExplanations();
712
713 // If all resources were served securely, add a Secure explanation.
714 if (this._schemeIsCryptographic && this._insecureContentStatus && (!this ._insecureContentStatus.displayedMixedContent && !this._insecureContentStatus.ra nMixedContent && !this._insecureContentStatus.displayedContentWithCertErrors && !this._insecureContentStatus.ranContentWithCertErrors)) {
715 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec urityAgent.SecurityStateExplanation} */ ({
716 "securityState": SecurityAgent.SecurityState.Secure,
717 "summary": WebInspector.UIString("Secure Resources"),
718 "description": WebInspector.UIString("All resources on this page are served securely.")
719 }));
720 }
721 },
722
723 _addMixedContentExplanations: function()
724 {
725 if (!this._schemeIsCryptographic)
726 return;
727
728 if (this._insecureContentStatus && (this._insecureContentStatus.ranMixed Content || this._insecureContentStatus.displayedMixedContent)) {
729 if (this._insecureContentStatus.ranMixedContent)
730 this._addMixedContentExplanation(this._securityExplanationsMain, this._insecureContentStatus.ranInsecureContentStyle, WebInspector.UIString("Act ive Mixed Content"), WebInspector.UIString("You have recently allowed non-secure content (such as scripts or iframes) to run on this site."), WebInspector.Netwo rkLogView.MixedContentFilterValues.BlockOverridden, showBlockOverriddenMixedCont entInNetworkPanel);
731 if (this._insecureContentStatus.displayedMixedContent)
732 this._addMixedContentExplanation(this._securityExplanationsMain, this._insecureContentStatus.displayedInsecureContentStyle, WebInspector.UIStrin g("Mixed Content"), WebInspector.UIString("The site includes HTTP resources."), WebInspector.NetworkLogView.MixedContentFilterValues.Displayed, showDisplayedMix edContentInNetworkPanel);
733 }
734
735 if (this._panel.filterRequestCount(WebInspector.NetworkLogView.MixedCont entFilterValues.Blocked) > 0)
736 this._addMixedContentExplanation(this._securityExplanationsExtra, Se curityAgent.SecurityState.Info, WebInspector.UIString("Blocked mixed content"), WebInspector.UIString("Your page requested non-secure resources that were blocke d."), WebInspector.NetworkLogView.MixedContentFilterValues.Blocked, showBlockedM ixedContentInNetworkPanel);
737
738 /**
739 * @param {!Event} e
740 */
741 function showDisplayedMixedContentInNetworkPanel(e)
742 {
743 e.consume();
744 WebInspector.NetworkPanel.revealAndFilter([
745 {
746 filterType: WebInspector.NetworkLogView.FilterType.MixedCont ent,
747 filterValue: WebInspector.NetworkLogView.MixedContentFilterV alues.Displayed
748 }
749 ]);
750 }
751
752 /**
753 * @param {!Event} e
754 */
755 function showBlockOverriddenMixedContentInNetworkPanel(e)
756 {
757 e.consume();
758 WebInspector.NetworkPanel.revealAndFilter([
759 {
760 filterType: WebInspector.NetworkLogView.FilterType.MixedCont ent,
761 filterValue: WebInspector.NetworkLogView.MixedContentFilterV alues.BlockOverridden
762 }
763 ]);
764 }
765
766 /**
767 * @param {!Event} e
768 */
769 function showBlockedMixedContentInNetworkPanel(e)
770 {
771 e.consume();
772 WebInspector.NetworkPanel.revealAndFilter([
773 {
774 filterType: WebInspector.NetworkLogView.FilterType.MixedCont ent,
775 filterValue: WebInspector.NetworkLogView.MixedContentFilterV alues.Blocked
776 }
777 ]);
778 }
779 },
780
781 /**
782 * @param {!Element} parent
783 * @param {!SecurityAgent.SecurityState} securityState
784 * @param {string} summary
785 * @param {string} description
786 * @param {!WebInspector.NetworkLogView.MixedContentFilterValues} filterKey
787 * @param {!Function} networkFilterFn
788 */
789 _addMixedContentExplanation: function(parent, securityState, summary, descri ption, filterKey, networkFilterFn)
790 {
791 var mixedContentExplanation = /** @type {!SecurityAgent.SecurityStateExp lanation} */ ({
792 "securityState": securityState,
793 "summary": summary,
794 "description": description
795 });
796
797 var explanation = this._addExplanation(parent, mixedContentExplanation);
798
799 var filterRequestCount = this._panel.filterRequestCount(filterKey);
800 if (!filterRequestCount) {
801 // Network instrumentation might not have been enabled for the page
802 // load, so the security panel does not necessarily know a count of
803 // individual mixed requests at this point. Prompt them to refresh
804 // instead of pointing them to the Network panel to get prompted
805 // to refresh.
806 var refreshPrompt = explanation.createChild("div", "security-mixed-c ontent");
807 refreshPrompt.textContent = WebInspector.UIString("Reload the page t o record requests for HTTP resources.");
808 return;
809 }
810
811 var requestsAnchor = explanation.createChild("div", "security-mixed-cont ent link");
812 if (filterRequestCount === 1) {
813 requestsAnchor.textContent = WebInspector.UIString("View %d request in Network Panel", filterRequestCount);
814 } else {
815 requestsAnchor.textContent = WebInspector.UIString("View %d requests in Network Panel", filterRequestCount);
816 }
817 requestsAnchor.href = "";
818 requestsAnchor.addEventListener("click", networkFilterFn);
819 },
820
821 _addContentWithCertErrorsExplanations: function()
822 {
823 if (!this._schemeIsCryptographic)
824 return;
825
826 if (!this._insecureContentStatus)
827 return;
828
829 if (this._insecureContentStatus.ranContentWithCertErrors) {
830 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec urityAgent.SecurityStateExplanation} */ ({
831 "securityState": this._insecureContentStatus.ranInsecureContentS tyle,
832 "summary": WebInspector.UIString("Active content with certificat e errors"),
833 "description": WebInspector.UIString("You have recently allowed content loaded with certificate errors (such as scripts or iframes) to run on th is site.")
834 }));
835 }
836
837 if (this._insecureContentStatus.displayedContentWithCertErrors) {
838 this._addExplanation(this._securityExplanationsMain, /** @type {!Sec urityAgent.SecurityStateExplanation} */ ({
839 "securityState": this._insecureContentStatus.displayedInsecureCo ntentStyle,
840 "summary": WebInspector.UIString("Content with certificate error s"),
841 "description": WebInspector.UIString("This site includes resourc es that were loaded with certificate errors.")
842 }));
843 }
844 },
845
846
847 __proto__: WebInspector.VBox.prototype
848 };
849
850 /**
851 * @constructor
852 * @extends {WebInspector.VBox}
853 * @param {!WebInspector.SecurityPanel} panel
854 * @param {!WebInspector.SecurityPanel.Origin} origin
855 * @param {!WebInspector.SecurityPanel.OriginState} originState
856 */
857 WebInspector.SecurityOriginView = function(panel, origin, originState)
858 {
859 WebInspector.VBox.call(this);
860 this._panel = panel; 834 this._panel = panel;
861 this.setMinimumSize(200, 100); 835 this.setMinimumSize(200, 100);
862 836
863 this.element.classList.add("security-origin-view"); 837 this.element.classList.add('security-origin-view');
864 this.registerRequiredCSS("security/originView.css"); 838 this.registerRequiredCSS('security/originView.css');
865 this.registerRequiredCSS("security/lockIcon.css"); 839 this.registerRequiredCSS('security/lockIcon.css');
866 840
867 var titleSection = this.element.createChild("div", "title-section"); 841 var titleSection = this.element.createChild('div', 'title-section');
868 var originDisplay = titleSection.createChild("div", "origin-display"); 842 var originDisplay = titleSection.createChild('div', 'origin-display');
869 this._originLockIcon = originDisplay.createChild("span", "security-property" ); 843 this._originLockIcon = originDisplay.createChild('span', 'security-property' );
870 this._originLockIcon.classList.add("security-property-" + originState.securi tyState); 844 this._originLockIcon.classList.add('security-property-' + originState.securi tyState);
871 // TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589 845 // TODO(lgarron): Highlight the origin scheme. https://crbug.com/523589
872 originDisplay.createChild("span", "origin").textContent = origin; 846 originDisplay.createChild('span', 'origin').textContent = origin;
873 var originNetworkLink = titleSection.createChild("div", "link"); 847 var originNetworkLink = titleSection.createChild('div', 'link');
874 originNetworkLink.textContent = WebInspector.UIString("View requests in Netw ork Panel"); 848 originNetworkLink.textContent = WebInspector.UIString('View requests in Netw ork Panel');
875 function showOriginRequestsInNetworkPanel() 849 function showOriginRequestsInNetworkPanel() {
876 { 850 var parsedURL = new WebInspector.ParsedURL(origin);
877 var parsedURL = new WebInspector.ParsedURL(origin); 851 WebInspector.NetworkPanel.revealAndFilter([
878 WebInspector.NetworkPanel.revealAndFilter([ 852 {filterType: WebInspector.NetworkLogView.FilterType.Domain, filterValue: parsedURL.host},
879 { 853 {filterType: WebInspector.NetworkLogView.FilterType.Scheme, filterValue: parsedURL.scheme}
880 filterType: WebInspector.NetworkLogView.FilterType.Domain, 854 ]);
881 filterValue: parsedURL.host 855 }
882 }, 856 originNetworkLink.addEventListener('click', showOriginRequestsInNetworkPanel , false);
883 {
884 filterType: WebInspector.NetworkLogView.FilterType.Scheme,
885 filterValue: parsedURL.scheme
886 }
887 ]);
888 }
889 originNetworkLink.addEventListener("click", showOriginRequestsInNetworkPanel , false);
890
891 857
892 if (originState.securityDetails) { 858 if (originState.securityDetails) {
893 var connectionSection = this.element.createChild("div", "origin-view-sec tion"); 859 var connectionSection = this.element.createChild('div', 'origin-view-secti on');
894 connectionSection.createChild("div", "origin-view-section-title").textCo ntent = WebInspector.UIString("Connection"); 860 connectionSection.createChild('div', 'origin-view-section-title').textCont ent =
895 861 WebInspector.UIString('Connection');
896 var table = new WebInspector.SecurityDetailsTable(); 862
897 connectionSection.appendChild(table.element()); 863 var table = new WebInspector.SecurityDetailsTable();
898 table.addRow("Protocol", originState.securityDetails.protocol); 864 connectionSection.appendChild(table.element());
899 if (originState.securityDetails.keyExchange) 865 table.addRow('Protocol', originState.securityDetails.protocol);
900 table.addRow("Key Exchange", originState.securityDetails.keyExchange ); 866 if (originState.securityDetails.keyExchange)
901 if (originState.securityDetails.keyExchangeGroup) 867 table.addRow('Key Exchange', originState.securityDetails.keyExchange);
902 table.addRow("Key Exchange Group", originState.securityDetails.keyEx changeGroup); 868 if (originState.securityDetails.keyExchangeGroup)
903 table.addRow("Cipher", originState.securityDetails.cipher + (originState .securityDetails.mac ? " with " + originState.securityDetails.mac : "")); 869 table.addRow('Key Exchange Group', originState.securityDetails.keyExchan geGroup);
904 870 table.addRow(
905 // Create the certificate section outside the callback, so that it appea rs in the right place. 871 'Cipher', originState.securityDetails.cipher +
906 var certificateSection = this.element.createChild("div", "origin-view-se ction"); 872 (originState.securityDetails.mac ? ' with ' + originState.security Details.mac : ''));
907 certificateSection.createChild("div", "origin-view-section-title").textC ontent = WebInspector.UIString("Certificate"); 873
908 874 // Create the certificate section outside the callback, so that it appears in the right place.
909 if (originState.securityDetails.signedCertificateTimestampList.length) { 875 var certificateSection = this.element.createChild('div', 'origin-view-sect ion');
910 // Create the Certificate Transparency section outside the callback, so that it appears in the right place. 876 certificateSection.createChild('div', 'origin-view-section-title').textCon tent =
911 var sctSection = this.element.createChild("div", "origin-view-sectio n"); 877 WebInspector.UIString('Certificate');
912 sctSection.createChild("div", "origin-view-section-title").textConte nt = WebInspector.UIString("Certificate Transparency"); 878
879 if (originState.securityDetails.signedCertificateTimestampList.length) {
880 // Create the Certificate Transparency section outside the callback, so that it appears in the right place.
881 var sctSection = this.element.createChild('div', 'origin-view-section');
882 sctSection.createChild('div', 'origin-view-section-title').textContent =
883 WebInspector.UIString('Certificate Transparency');
884 }
885
886 var sanDiv = this._createSanDiv(originState.securityDetails.sanList);
887 var validFromString = new Date(1000 * originState.securityDetails.validFro m).toUTCString();
888 var validUntilString = new Date(1000 * originState.securityDetails.validTo ).toUTCString();
889
890 table = new WebInspector.SecurityDetailsTable();
891 certificateSection.appendChild(table.element());
892 table.addRow(WebInspector.UIString('Subject'), originState.securityDetails .subjectName);
893 table.addRow(WebInspector.UIString('SAN'), sanDiv);
894 table.addRow(WebInspector.UIString('Valid From'), validFromString);
895 table.addRow(WebInspector.UIString('Valid Until'), validUntilString);
896 table.addRow(WebInspector.UIString('Issuer'), originState.securityDetails. issuer);
897 table.addRow(
898 '', WebInspector.SecurityPanel.createCertificateViewerButton2(
899 WebInspector.UIString('Open full certificate details'), origin ));
900
901 if (!originState.securityDetails.signedCertificateTimestampList.length)
902 return;
903
904 // Show summary of SCT(s) of Certificate Transparency.
905 var sctSummaryTable = new WebInspector.SecurityDetailsTable();
906 sctSummaryTable.element().classList.add('sct-summary');
907 sctSection.appendChild(sctSummaryTable.element());
908 for (var i = 0; i < originState.securityDetails.signedCertificateTimestamp List.length; i++) {
909 var sct = originState.securityDetails.signedCertificateTimestampList[i];
910 sctSummaryTable.addRow(
911 WebInspector.UIString('SCT'), sct.logDescription + ' (' + sct.origin + ', ' + sct.status + ')');
912 }
913
914 // Show detailed SCT(s) of Certificate Transparency.
915 var sctTableWrapper = sctSection.createChild('div', 'sct-details');
916 sctTableWrapper.classList.add('hidden');
917 for (var i = 0; i < originState.securityDetails.signedCertificateTimestamp List.length; i++) {
918 var sctTable = new WebInspector.SecurityDetailsTable();
919 sctTableWrapper.appendChild(sctTable.element());
920 var sct = originState.securityDetails.signedCertificateTimestampList[i];
921 sctTable.addRow(WebInspector.UIString('Log Name'), sct.logDescription);
922 sctTable.addRow(WebInspector.UIString('Log ID'), sct.logId.replace(/(.{2 })/g, '$1 '));
923 sctTable.addRow(WebInspector.UIString('Validation Status'), sct.status);
924 sctTable.addRow(WebInspector.UIString('Source'), sct.origin);
925 sctTable.addRow(WebInspector.UIString('Issued At'), new Date(sct.timesta mp).toUTCString());
926 sctTable.addRow(WebInspector.UIString('Hash Algorithm'), sct.hashAlgorit hm);
927 sctTable.addRow(WebInspector.UIString('Signature Algorithm'), sct.signat ureAlgorithm);
928 sctTable.addRow(WebInspector.UIString('Signature Data'), sct.signatureDa ta.replace(/(.{2})/g, '$1 '));
929 }
930
931 // Add link to toggle between displaying of the summary of the SCT(s) and the detailed SCT(s).
932 var toggleSctsDetailsLink = sctSection.createChild('div', 'link');
933 toggleSctsDetailsLink.classList.add('sct-toggle');
934 toggleSctsDetailsLink.textContent = WebInspector.UIString('Show full detai ls');
935 function toggleSctDetailsDisplay() {
936 var isDetailsShown = !sctTableWrapper.classList.contains('hidden');
937 if (isDetailsShown)
938 toggleSctsDetailsLink.textContent = WebInspector.UIString('Show full d etails');
939 else
940 toggleSctsDetailsLink.textContent = WebInspector.UIString('Hide full d etails');
941 sctSummaryTable.element().classList.toggle('hidden');
942 sctTableWrapper.classList.toggle('hidden');
943 }
944 toggleSctsDetailsLink.addEventListener('click', toggleSctDetailsDisplay, f alse);
945
946 var noteSection = this.element.createChild('div', 'origin-view-section');
947 // TODO(lgarron): Fix the issue and then remove this section. See comment in SecurityPanel._processRequest().
948 noteSection.createChild('div').textContent =
949 WebInspector.UIString('The security details above are from the first i nspected response.');
950 } else if (originState.securityState !== SecurityAgent.SecurityState.Unknown ) {
951 var notSecureSection = this.element.createChild('div', 'origin-view-sectio n');
952 notSecureSection.createChild('div', 'origin-view-section-title').textConte nt =
953 WebInspector.UIString('Not Secure');
954 notSecureSection.createChild('div').textContent =
955 WebInspector.UIString('Your connection to this origin is not secure.') ;
956 } else {
957 var noInfoSection = this.element.createChild('div', 'origin-view-section') ;
958 noInfoSection.createChild('div', 'origin-view-section-title').textContent =
959 WebInspector.UIString('No Security Information');
960 noInfoSection.createChild('div').textContent =
961 WebInspector.UIString('No security details are available for this orig in.');
962 }
963 }
964
965 /**
966 * @param {!Array<string>} sanList
967 * *return {!Element}
968 */
969 _createSanDiv(sanList) {
970 var sanDiv = createElement('div');
971 if (sanList.length === 0) {
972 sanDiv.textContent = WebInspector.UIString('(N/A)');
973 sanDiv.classList.add('empty-san');
974 } else {
975 var truncatedNumToShow = 2;
976 var listIsTruncated = sanList.length > truncatedNumToShow + 1;
977 for (var i = 0; i < sanList.length; i++) {
978 var span = sanDiv.createChild('span', 'san-entry');
979 span.textContent = sanList[i];
980 if (listIsTruncated && i >= truncatedNumToShow)
981 span.classList.add('truncated-entry');
982 }
983 if (listIsTruncated) {
984 var truncatedSANToggle = sanDiv.createChild('div', 'link');
985 truncatedSANToggle.href = '';
986
987 function toggleSANTruncation() {
988 if (sanDiv.classList.contains('truncated-san')) {
989 sanDiv.classList.remove('truncated-san');
990 truncatedSANToggle.textContent = WebInspector.UIString('Show less');
991 } else {
992 sanDiv.classList.add('truncated-san');
993 truncatedSANToggle.textContent = WebInspector.UIString('Show more (% d total)', sanList.length);
994 }
913 } 995 }
914 996 truncatedSANToggle.addEventListener('click', toggleSANTruncation, false) ;
915 var sanDiv = this._createSanDiv(originState.securityDetails.sanList); 997 toggleSANTruncation();
916 var validFromString = new Date(1000 * originState.securityDetails.validF rom).toUTCString(); 998 }
917 var validUntilString = new Date(1000 * originState.securityDetails.valid To).toUTCString(); 999 }
918 1000 return sanDiv;
919 table = new WebInspector.SecurityDetailsTable(); 1001 }
920 certificateSection.appendChild(table.element()); 1002
921 table.addRow(WebInspector.UIString("Subject"), originState.securityDetai ls.subjectName); 1003 /**
922 table.addRow(WebInspector.UIString("SAN"), sanDiv); 1004 * @param {!SecurityAgent.SecurityState} newSecurityState
923 table.addRow(WebInspector.UIString("Valid From"), validFromString); 1005 */
924 table.addRow(WebInspector.UIString("Valid Until"), validUntilString); 1006 setSecurityState(newSecurityState) {
925 table.addRow(WebInspector.UIString("Issuer"), originState.securityDetail s.issuer); 1007 for (var className of Array.prototype.slice.call(this._originLockIcon.classL ist)) {
926 table.addRow("", WebInspector.SecurityPanel.createCertificateViewerButto n2(WebInspector.UIString("Open full certificate details"), origin)); 1008 if (className.startsWith('security-property-'))
927 1009 this._originLockIcon.classList.remove(className);
928 if (!originState.securityDetails.signedCertificateTimestampList.length) 1010 }
929 return; 1011
930 1012 this._originLockIcon.classList.add('security-property-' + newSecurityState);
931 // Show summary of SCT(s) of Certificate Transparency. 1013 }
932 var sctSummaryTable = new WebInspector.SecurityDetailsTable(); 1014 };
933 sctSummaryTable.element().classList.add("sct-summary"); 1015
934 sctSection.appendChild(sctSummaryTable.element()); 1016 /**
935 for (var i = 0; i < originState.securityDetails.signedCertificateTimesta mpList.length; i++) 1017 * @unrestricted
936 { 1018 */
937 var sct = originState.securityDetails.signedCertificateTimestampList [i]; 1019 WebInspector.SecurityDetailsTable = class {
938 sctSummaryTable.addRow(WebInspector.UIString("SCT"), sct.logDescript ion + " (" + sct.origin + ", " + sct.status + ")"); 1020 constructor() {
939 } 1021 this._element = createElement('table');
940 1022 this._element.classList.add('details-table');
941 // Show detailed SCT(s) of Certificate Transparency. 1023 }
942 var sctTableWrapper = sctSection.createChild("div", "sct-details"); 1024
943 sctTableWrapper.classList.add("hidden"); 1025 /**
944 for (var i = 0; i < originState.securityDetails.signedCertificateTimesta mpList.length; i++) 1026 * @return: {!Element}
945 { 1027 */
946 var sctTable = new WebInspector.SecurityDetailsTable(); 1028 element() {
947 sctTableWrapper.appendChild(sctTable.element()); 1029 return this._element;
948 var sct = originState.securityDetails.signedCertificateTimestampList [i]; 1030 }
949 sctTable.addRow(WebInspector.UIString("Log Name"), sct.logDescriptio n); 1031
950 sctTable.addRow(WebInspector.UIString("Log ID"), sct.logId.replace(/ (.{2})/g,"$1 ")); 1032 /**
951 sctTable.addRow(WebInspector.UIString("Validation Status"), sct.stat us); 1033 * @param {string} key
952 sctTable.addRow(WebInspector.UIString("Source"), sct.origin); 1034 * @param {string|!Node} value
953 sctTable.addRow(WebInspector.UIString("Issued At"), new Date(sct.tim estamp).toUTCString()); 1035 */
954 sctTable.addRow(WebInspector.UIString("Hash Algorithm"), sct.hashAlg orithm); 1036 addRow(key, value) {
955 sctTable.addRow(WebInspector.UIString("Signature Algorithm"), sct.si gnatureAlgorithm); 1037 var row = this._element.createChild('div', 'details-table-row');
956 sctTable.addRow(WebInspector.UIString("Signature Data"), sct.signatu reData.replace(/(.{2})/g,"$1 ")); 1038 row.createChild('div').textContent = key;
957 } 1039
958 1040 var valueDiv = row.createChild('div');
959 // Add link to toggle between displaying of the summary of the SCT(s) an d the detailed SCT(s). 1041 if (typeof value === 'string') {
960 var toggleSctsDetailsLink = sctSection.createChild("div", "link"); 1042 valueDiv.textContent = value;
961 toggleSctsDetailsLink.classList.add("sct-toggle");
962 toggleSctsDetailsLink.textContent = WebInspector.UIString("Show full det ails");
963 function toggleSctDetailsDisplay()
964 {
965 var isDetailsShown = !sctTableWrapper.classList.contains("hidden");
966 if (isDetailsShown)
967 toggleSctsDetailsLink.textContent = WebInspector.UIString("Show full details");
968 else
969 toggleSctsDetailsLink.textContent = WebInspector.UIString("Hide full details");
970 sctSummaryTable.element().classList.toggle("hidden");
971 sctTableWrapper.classList.toggle("hidden");
972 }
973 toggleSctsDetailsLink.addEventListener("click", toggleSctDetailsDisplay, false);
974
975 var noteSection = this.element.createChild("div", "origin-view-section") ;
976 // TODO(lgarron): Fix the issue and then remove this section. See commen t in SecurityPanel._processRequest().
977 noteSection.createChild("div").textContent = WebInspector.UIString("The security details above are from the first inspected response.");
978 } else if (originState.securityState !== SecurityAgent.SecurityState.Unknown ) {
979 var notSecureSection = this.element.createChild("div", "origin-view-sect ion");
980 notSecureSection.createChild("div", "origin-view-section-title").textCon tent = WebInspector.UIString("Not Secure");
981 notSecureSection.createChild("div").textContent = WebInspector.UIString( "Your connection to this origin is not secure.");
982 } else { 1043 } else {
983 var noInfoSection = this.element.createChild("div", "origin-view-section "); 1044 valueDiv.appendChild(value);
984 noInfoSection.createChild("div", "origin-view-section-title").textConten t = WebInspector.UIString("No Security Information"); 1045 }
985 noInfoSection.createChild("div").textContent = WebInspector.UIString("No security details are available for this origin."); 1046 }
986 }
987 }; 1047 };
988
989 WebInspector.SecurityOriginView.prototype = {
990
991 /**
992 * @param {!Array<string>} sanList
993 * *return {!Element}
994 */
995 _createSanDiv: function(sanList)
996 {
997 var sanDiv = createElement("div");
998 if (sanList.length === 0) {
999 sanDiv.textContent = WebInspector.UIString("(N/A)");
1000 sanDiv.classList.add("empty-san");
1001 } else {
1002 var truncatedNumToShow = 2;
1003 var listIsTruncated = sanList.length > truncatedNumToShow + 1;
1004 for (var i = 0; i < sanList.length; i++) {
1005 var span = sanDiv.createChild("span", "san-entry");
1006 span.textContent = sanList[i];
1007 if (listIsTruncated && i >= truncatedNumToShow)
1008 span.classList.add("truncated-entry");
1009 }
1010 if (listIsTruncated) {
1011 var truncatedSANToggle = sanDiv.createChild("div", "link");
1012 truncatedSANToggle.href = "";
1013
1014 function toggleSANTruncation()
1015 {
1016 if (sanDiv.classList.contains("truncated-san")) {
1017 sanDiv.classList.remove("truncated-san");
1018 truncatedSANToggle.textContent = WebInspector.UIString(" Show less");
1019 } else {
1020 sanDiv.classList.add("truncated-san");
1021 truncatedSANToggle.textContent = WebInspector.UIString(" Show more (%d total)", sanList.length);
1022 }
1023 }
1024 truncatedSANToggle.addEventListener("click", toggleSANTruncation , false);
1025 toggleSANTruncation();
1026 }
1027 }
1028 return sanDiv;
1029 },
1030
1031 /**
1032 * @param {!SecurityAgent.SecurityState} newSecurityState
1033 */
1034 setSecurityState: function(newSecurityState)
1035 {
1036 for (var className of Array.prototype.slice.call(this._originLockIcon.cl assList)) {
1037 if (className.startsWith("security-property-"))
1038 this._originLockIcon.classList.remove(className);
1039 }
1040
1041 this._originLockIcon.classList.add("security-property-" + newSecuritySta te);
1042 },
1043
1044 __proto__: WebInspector.VBox.prototype
1045 };
1046
1047 /**
1048 * @constructor
1049 */
1050 WebInspector.SecurityDetailsTable = function()
1051 {
1052 this._element = createElement("table");
1053 this._element.classList.add("details-table");
1054 };
1055
1056 WebInspector.SecurityDetailsTable.prototype = {
1057
1058 /**
1059 * @return: {!Element}
1060 */
1061 element: function()
1062 {
1063 return this._element;
1064 },
1065
1066 /**
1067 * @param {string} key
1068 * @param {string|!Node} value
1069 */
1070 addRow: function(key, value)
1071 {
1072 var row = this._element.createChild("div", "details-table-row");
1073 row.createChild("div").textContent = key;
1074
1075 var valueDiv = row.createChild("div");
1076 if (typeof value === "string") {
1077 valueDiv.textContent = value;
1078 } else {
1079 valueDiv.appendChild(value);
1080 }
1081 }
1082 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698