[geary/wip/135-contact-popovers: 56/56] Implement spoofed email address UI for ContactsPopover
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/wip/135-contact-popovers: 56/56] Implement spoofed email address UI for ContactsPopover
- Date: Sun, 7 Apr 2019 01:46:44 +0000 (UTC)
commit 6536e2cc07712390402b759e64155f058c8c329c
Author: Michael Gratton <mike vee net>
Date: Wed Mar 27 17:07:28 2019 +1100
Implement spoofed email address UI for ContactsPopover
.../conversation-contact-popover.vala | 84 ++--
.../conversation-viewer/conversation-message.vala | 7 +-
ui/conversation-contact-popover.ui | 431 ++++++++++++++-------
ui/geary.css | 4 +
4 files changed, 345 insertions(+), 181 deletions(-)
---
diff --git a/src/client/conversation-viewer/conversation-contact-popover.vala
b/src/client/conversation-viewer/conversation-contact-popover.vala
index f7a95523..3f2dc10c 100644
--- a/src/client/conversation-viewer/conversation-contact-popover.vala
+++ b/src/client/conversation-viewer/conversation-contact-popover.vala
@@ -41,6 +41,9 @@ public class Conversation.ContactPopover : Gtk.Popover {
private GLib.Cancellable load_cancellable = new GLib.Cancellable();
+ [GtkChild]
+ private Gtk.Grid contact_pane;
+
[GtkChild]
private Gtk.Image avatar;
@@ -65,6 +68,15 @@ public class Conversation.ContactPopover : Gtk.Popover {
[GtkChild]
private Gtk.ModelButton load_remote_button;
+ [GtkChild]
+ private Gtk.Grid deceptive_pane;
+
+ [GtkChild]
+ private Gtk.Label forged_email_label;
+
+ [GtkChild]
+ private Gtk.Label actual_email_label;
+
private GLib.SimpleActionGroup actions = new GLib.SimpleActionGroup();
@@ -125,40 +137,52 @@ public class Conversation.ContactPopover : Gtk.Popover {
}
private void update() {
- string display_name = this.contact.display_name;
- this.contact_name.set_text(display_name);
+ if (!this.mailbox.is_spoofed()) {
+ this.contact_pane.show();
+ this.deceptive_pane.hide();
+
+ string display_name = this.contact.display_name;
+ this.contact_name.set_text(display_name);
+
+ if (!this.contact.display_name_is_email) {
+ this.contact_address.set_text(this.mailbox.address);
+ } else {
+ this.contact_name.vexpand = true;
+ this.contact_name.valign = FILL;
+ this.contact_address.hide();
+ }
- if (!this.contact.display_name_is_email) {
- this.contact_address.set_text(this.mailbox.address);
- } else {
- this.contact_name.vexpand = true;
- this.contact_name.valign = FILL;
- this.contact_address.hide();
- }
+ bool is_desktop = this.contact.is_desktop_contact;
- bool is_desktop = this.contact.is_desktop_contact;
+ bool starred = false;
+ bool unstarred = false;
+ if (is_desktop) {
+ starred = this.contact.is_favourite;
+ unstarred = !this.contact.is_favourite;
+ }
+ this.starred_button.set_visible(starred);
+ this.unstarred_button.set_visible(unstarred);
+
+ this.open_button.set_visible(is_desktop);
+ this.save_button.set_visible(!is_desktop);
+ this.load_remote_button.set_visible(!is_desktop);
+
+ GLib.SimpleAction load_remote = (GLib.SimpleAction)
+ actions.lookup_action(ACTION_LOAD_REMOTE);
+ load_remote.set_state(
+ new GLib.Variant.boolean(
+ is_desktop || this.contact.load_remote_resources
+ )
+ );
+ } else {
+ this.deceptive_pane.show();
+ this.contact_pane.hide();
- bool starred = false;
- bool unstarred = false;
- if (is_desktop) {
- starred = this.contact.is_favourite;
- unstarred = !this.contact.is_favourite;
+ this.forged_email_label.label = Geary.String.reduce_whitespace(
+ this.mailbox.name
+ );
+ this.actual_email_label.label = this.mailbox.address;
}
- this.starred_button.set_visible(starred);
- this.unstarred_button.set_visible(unstarred);
-
-
- this.open_button.set_visible(is_desktop);
- this.save_button.set_visible(!is_desktop);
- this.load_remote_button.set_visible(!is_desktop);
-
- GLib.SimpleAction load_remote = (GLib.SimpleAction)
- actions.lookup_action(ACTION_LOAD_REMOTE);
- load_remote.set_state(
- new GLib.Variant.boolean(
- is_desktop || this.contact.load_remote_resources
- )
- );
}
private async void open() {
diff --git a/src/client/conversation-viewer/conversation-message.vala
b/src/client/conversation-viewer/conversation-message.vala
index ce8588d0..d423ba55 100644
--- a/src/client/conversation-viewer/conversation-message.vala
+++ b/src/client/conversation-viewer/conversation-message.vala
@@ -146,9 +146,10 @@ public class ConversationMessage : Gtk.Grid, Geary.BaseInterface {
// reduce the chance of the user of being tricked by
// malware.
primary.set_text(display_address);
- this.displayed = new Geary.RFC822.MailboxAddress(
- null, this.source.address
- );
+ // Use the source as the displayed address so that the
+ // contact popover uses the spoofed mailbox and
+ // displays it as being spoofed.
+ this.displayed = this.source;
} else if (this.contact.is_trusted) {
// The contact's name can be trusted, so no need to
// display the email address
diff --git a/ui/conversation-contact-popover.ui b/ui/conversation-contact-popover.ui
index ca98a8fc..c899fb09 100644
--- a/ui/conversation-contact-popover.ui
+++ b/ui/conversation-contact-popover.ui
@@ -9,82 +9,248 @@
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin_left">10</property>
- <property name="margin_right">10</property>
- <property name="margin_top">10</property>
- <property name="margin_bottom">10</property>
<property name="orientation">vertical</property>
<child>
- <object class="GtkGrid">
+ <object class="GtkGrid" id="contact_pane">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="margin_bottom">6</property>
- <property name="column_spacing">12</property>
+ <property name="margin_left">10</property>
+ <property name="margin_right">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkButton" id="unstarred_button">
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="action_name">con.star</property>
- <property name="relief">none</property>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_bottom">6</property>
+ <property name="column_spacing">12</property>
<child>
- <object class="GtkImage">
+ <object class="GtkButton" id="unstarred_button">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="action_name">con.star</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">non-starred-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="starred_button">
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="action_name">con.unstar</property>
+ <property name="relief">none</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">starred-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkImage" id="avatar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="pixel_size">48</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="icon_name">non-starred-symbolic</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="contact_name">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">end</property>
+ <property name="vexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="contact_address">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="margin_top">2</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">True</property>
+ <property name="ellipsize">middle</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
</object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
</child>
</object>
<packing>
- <property name="left_attach">2</property>
+ <property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="starred_button">
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkModelButton">
+ <property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
- <property name="halign">end</property>
- <property name="valign">center</property>
- <property name="action_name">con.unstar</property>
- <property name="relief">none</property>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">starred-symbolic</property>
- </object>
- </child>
+ <property name="action_name">con.new-conversation</property>
+ <property name="text" translatable="yes">New Conversation…</property>
</object>
<packing>
- <property name="left_attach">3</property>
- <property name="top_attach">0</property>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
</packing>
</child>
<child>
- <object class="GtkImage" id="avatar">
+ <object class="GtkModelButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">con.copy-email</property>
+ <property name="text" translatable="yes">Copy Email Address</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="pixel_size">48</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="save_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">con.save</property>
+ <property name="text" translatable="yes">Save in Contacts…</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">7</property>
</packing>
</child>
+ <child>
+ <object class="GtkModelButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">con.show-conversations</property>
+ <property name="text" translatable="yes">Show Conversations</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="open_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">con.open</property>
+ <property name="text" translatable="yes">Open in Contacts</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkModelButton" id="load_remote_button">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">con.load-remote</property>
+ <property name="text" translatable="yes">Always Load Remote Images</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="deceptive_pane">
+ <property name="can_focus">False</property>
+ <property name="margin_left">10</property>
+ <property name="margin_right">10</property>
+ <property name="margin_top">10</property>
+ <property name="margin_bottom">10</property>
+ <property name="orientation">vertical</property>
+ <property name="row_spacing">6</property>
<child>
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
+ <property name="column_spacing">12</property>
<child>
- <object class="GtkLabel" id="contact_name">
+ <object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="valign">end</property>
- <property name="vexpand">True</property>
+ <property name="pixel_size">36</property>
+ <property name="icon_name">dialog-warning-symbolic</property>
</object>
<packing>
<property name="left_attach">0</property>
@@ -92,134 +258,103 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="contact_address">
+ <object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="valign">start</property>
- <property name="margin_top">2</property>
- <property name="hexpand">False</property>
- <property name="vexpand">True</property>
- <property name="ellipsize">middle</property>
+ <property name="label" translatable="yes" comments="Title label on contact
popover">Deceptive email address</property>
<style>
- <class name="dim-label"/>
+ <class name="title"/>
</style>
</object>
<packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
- <property name="left_attach">1</property>
+ <property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" comments="Contact popover label">This email
address is:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="actual_email_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="geary-deceptive"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" comments="Contact popover label">But was forged
as:</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="forged_email_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <style>
+ <class name="geary-deceptive"/>
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="label" translatable="yes" comments="Contact popover label">The sender may
not be trustworthy</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
- <child>
- <object class="GtkModelButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.new-conversation</property>
- <property name="text" translatable="yes">_New Conversation…</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.copy-email</property>
- <property name="text" translatable="yes">Copy Email _Address</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkModelButton" id="save_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.save</property>
- <property name="text" translatable="yes">Save in Contacts…</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">7</property>
- </packing>
- </child>
- <child>
- <object class="GtkModelButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.show-conversations</property>
- <property name="text" translatable="yes">Show Conversations</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">5</property>
- </packing>
- </child>
- <child>
- <object class="GtkModelButton" id="open_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.open</property>
- <property name="text" translatable="yes">Open in Contacts</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">6</property>
- </packing>
- </child>
- <child>
- <object class="GtkModelButton" id="load_remote_button">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">con.load-remote</property>
- <property name="text" translatable="yes">Always Load Remote Images</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">8</property>
- </packing>
- </child>
</object>
</child>
<style>
diff --git a/ui/geary.css b/ui/geary.css
index b7c061b4..10507392 100644
--- a/ui/geary.css
+++ b/ui/geary.css
@@ -180,6 +180,10 @@ grid.geary-message-summary {
font-size: 80%;
}
+.geary-contact-popover .geary-deceptive {
+ font-weight: bold;
+}
+
/* Composer */
.geary-composer-embed headerbar {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]