portalHelper: Add security icon to titlebar
This adds a security icon (either secure or insecure) to the portal helper's title bar. As soon as a part or all of the page and its content is served insecurely, the icon shown will be a broken padlock. https://bugzilla.gnome.org/show_bug.cgi?id=749197
This commit is contained in:
parent
18074951b9
commit
304b68eff9
@ -20,6 +20,12 @@ const PortalHelperResult = {
|
|||||||
RECHECK: 2
|
RECHECK: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PortalHelperSecurityLevel = {
|
||||||
|
NOT_YET_DETERMINED: 0,
|
||||||
|
SECURE: 1,
|
||||||
|
INSECURE: 2
|
||||||
|
};
|
||||||
|
|
||||||
const INACTIVITY_TIMEOUT = 30000; //ms
|
const INACTIVITY_TIMEOUT = 30000; //ms
|
||||||
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
const CONNECTIVITY_CHECK_HOST = 'nmcheck.gnome.org';
|
||||||
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
const CONNECTIVITY_CHECK_URI = 'http://' + CONNECTIVITY_CHECK_HOST;
|
||||||
@ -45,6 +51,71 @@ const HelperDBusInterface = '<node> \
|
|||||||
</interface> \
|
</interface> \
|
||||||
</node>';
|
</node>';
|
||||||
|
|
||||||
|
const PortalHeaderBar = new Lang.Class({
|
||||||
|
Name: 'PortalHeaderBar',
|
||||||
|
Extends: Gtk.HeaderBar,
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.parent({ show_close_button: true });
|
||||||
|
|
||||||
|
// See ephy-title-box.c in epiphany for the layout
|
||||||
|
let vbox = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
spacing: 0 });
|
||||||
|
this.set_custom_title(vbox);
|
||||||
|
|
||||||
|
/* TRANSLATORS: this is the title of the wifi captive portal login window */
|
||||||
|
let titleLabel = new Gtk.Label({ label: _("Hotspot Login"),
|
||||||
|
wrap: false,
|
||||||
|
single_line_mode: true,
|
||||||
|
ellipsize: Pango.EllipsizeMode.END });
|
||||||
|
titleLabel.get_style_context().add_class('title');
|
||||||
|
vbox.add(titleLabel);
|
||||||
|
|
||||||
|
let hbox = new Gtk.Box({ orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
spacing: 4,
|
||||||
|
halign: Gtk.Align.CENTER,
|
||||||
|
valign: Gtk.Align.BASELINE });
|
||||||
|
hbox.get_style_context().add_class('subtitle');
|
||||||
|
vbox.add(hbox);
|
||||||
|
|
||||||
|
this._lockImage = new Gtk.Image({ icon_size: Gtk.IconSize.MENU,
|
||||||
|
valign: Gtk.Align.BASELINE });
|
||||||
|
hbox.add(this._lockImage);
|
||||||
|
|
||||||
|
this.subtitleLabel = new Gtk.Label({ wrap: false,
|
||||||
|
single_line_mode: true,
|
||||||
|
ellipsize: Pango.EllipsizeMode.END,
|
||||||
|
valign: Gtk.Align.BASELINE,
|
||||||
|
selectable: true});
|
||||||
|
this.subtitleLabel.get_style_context().add_class('subtitle');
|
||||||
|
hbox.add(this.subtitleLabel);
|
||||||
|
|
||||||
|
vbox.show_all();
|
||||||
|
},
|
||||||
|
|
||||||
|
setSubtitle: function(label) {
|
||||||
|
this.subtitleLabel.set_text(label);
|
||||||
|
},
|
||||||
|
|
||||||
|
setSecurityIcon: function(securityLevel) {
|
||||||
|
switch (securityLevel) {
|
||||||
|
case PortalHelperSecurityLevel.NOT_YET_DETERMINED:
|
||||||
|
this._lockImage.hide();
|
||||||
|
break;
|
||||||
|
case PortalHelperSecurityLevel.SECURE:
|
||||||
|
this._lockImage.show();
|
||||||
|
this._lockImage.set_from_icon_name("channel-secure-symbolic", Gtk.IconSize.MENU);
|
||||||
|
this._lockImage.set_tooltip_text(null);
|
||||||
|
break;
|
||||||
|
case PortalHelperSecurityLevel.INSECURE:
|
||||||
|
this._lockImage.show();
|
||||||
|
this._lockImage.set_from_icon_name("channel-insecure-symbolic", Gtk.IconSize.MENU);
|
||||||
|
this._lockImage.set_tooltip_text(_('Your connection to this hotspot login is not secure. Passwords or other information you enter on this page can be viewed by people nearby.'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const PortalWindow = new Lang.Class({
|
const PortalWindow = new Lang.Class({
|
||||||
Name: 'PortalWindow',
|
Name: 'PortalWindow',
|
||||||
Extends: Gtk.ApplicationWindow,
|
Extends: Gtk.ApplicationWindow,
|
||||||
@ -53,9 +124,8 @@ const PortalWindow = new Lang.Class({
|
|||||||
this.parent({ application: application });
|
this.parent({ application: application });
|
||||||
|
|
||||||
this.connect('delete-event', Lang.bind(this, this.destroyWindow));
|
this.connect('delete-event', Lang.bind(this, this.destroyWindow));
|
||||||
/* TRANSLATORS: this is the title of the wifi captive portal login window */
|
this._headerBar = new PortalHeaderBar();
|
||||||
this._headerBar = new Gtk.HeaderBar({ title: _("Hotspot Login"),
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||||
show_close_button: true });
|
|
||||||
this.set_titlebar(this._headerBar);
|
this.set_titlebar(this._headerBar);
|
||||||
this._headerBar.show();
|
this._headerBar.show();
|
||||||
|
|
||||||
@ -81,6 +151,8 @@ const PortalWindow = new Lang.Class({
|
|||||||
|
|
||||||
this._webView = WebKit.WebView.new_with_context(webContext);
|
this._webView = WebKit.WebView.new_with_context(webContext);
|
||||||
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
this._webView.connect('decide-policy', Lang.bind(this, this._onDecidePolicy));
|
||||||
|
this._webView.connect('load-changed', Lang.bind(this, this._onLoadChanged));
|
||||||
|
this._webView.connect('insecure-content-detected', Lang.bind(this, this._onInsecureContentDetected));
|
||||||
this._webView.load_uri(url);
|
this._webView.load_uri(url);
|
||||||
this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
|
this._webView.connect('notify::uri', Lang.bind(this, this._syncUri));
|
||||||
this._syncUri();
|
this._syncUri();
|
||||||
@ -102,9 +174,9 @@ const PortalWindow = new Lang.Class({
|
|||||||
_syncUri: function() {
|
_syncUri: function() {
|
||||||
let uri = this._webView.uri;
|
let uri = this._webView.uri;
|
||||||
if (uri)
|
if (uri)
|
||||||
this._headerBar.set_subtitle(GLib.uri_unescape_string(uri, null, false));
|
this._headerBar.setSubtitle(GLib.uri_unescape_string(uri, null));
|
||||||
else
|
else
|
||||||
this._headerBar.set_subtitle(null);
|
this._headerBar.setSubtitle(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
@ -120,6 +192,24 @@ const PortalWindow = new Lang.Class({
|
|||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onLoadChanged: function(loadEvent) {
|
||||||
|
if (loadEvent == WebKit.LOAD_STARTED) {
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.NOT_YET_DETERMINED);
|
||||||
|
} else if (loadEvent == WebKit.LOAD_COMMITTED) {
|
||||||
|
let tlsInfo = this._webView.get_tls_info();
|
||||||
|
let ret = tlsInfo[0];
|
||||||
|
let flags = tlsInfo[2];
|
||||||
|
if (ret && flags == 0)
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.SECURE);
|
||||||
|
else
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onInsecureContentDetected: function (insecureContentEvent) {
|
||||||
|
this._headerBar.setSecurityIcon(PortalHelperSecurityLevel.INSECURE);
|
||||||
|
},
|
||||||
|
|
||||||
_onDecidePolicy: function(view, decision, type) {
|
_onDecidePolicy: function(view, decision, type) {
|
||||||
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
if (type == WebKit.PolicyDecisionType.NEW_WINDOW_ACTION) {
|
||||||
decision.ignore();
|
decision.ignore();
|
||||||
|
Loading…
Reference in New Issue
Block a user