openpgp: contact details provider (fingerprint), colored fingerprints, fix shown availability
This commit is contained in:
parent
b0264b3e00
commit
3ddc53e683
|
@ -30,6 +30,7 @@ vala_precompile(OPENPGP_VALA_C
|
||||||
SOURCES
|
SOURCES
|
||||||
src/account_settings_entry.vala
|
src/account_settings_entry.vala
|
||||||
src/account_settings_widget.vala
|
src/account_settings_widget.vala
|
||||||
|
src/contact_details_provider.vala
|
||||||
src/database.vala
|
src/database.vala
|
||||||
src/encryption_list_entry.vala
|
src/encryption_list_entry.vala
|
||||||
src/manager.vala
|
src/manager.vala
|
||||||
|
@ -37,6 +38,7 @@ SOURCES
|
||||||
src/register_plugin.vala
|
src/register_plugin.vala
|
||||||
src/stream_flag.vala
|
src/stream_flag.vala
|
||||||
src/stream_module.vala
|
src/stream_module.vala
|
||||||
|
src/util.vala
|
||||||
CUSTOM_VAPIS
|
CUSTOM_VAPIS
|
||||||
${CMAKE_BINARY_DIR}/exports/gpgme.vapi
|
${CMAKE_BINARY_DIR}/exports/gpgme.vapi
|
||||||
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
|
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
|
||||||
|
|
|
@ -77,10 +77,10 @@ private class AccountSettingsWidget : Stack, Plugins.AccountSettingsWidget {
|
||||||
|
|
||||||
TreeIter iter;
|
TreeIter iter;
|
||||||
list_store.append(out iter);
|
list_store.append(out iter);
|
||||||
list_store.set(iter, 0, build_markup_string(_("Key publishing disabled"), _("Select key")), 1, "");
|
list_store.set(iter, 0, build_markup_string(_("Key publishing disabled"), _("Select key") + "<span font_family='monospace' font='8'> \n </span>"), 1, "");
|
||||||
for (int i = 0; i < keys.size; i++) {
|
for (int i = 0; i < keys.size; i++) {
|
||||||
list_store.append(out iter);
|
list_store.append(out iter);
|
||||||
list_store.set(iter, 0, @"$(Markup.escape_text(keys[i].uids[0].uid))\n<span font_family='monospace' font='8'>0x$(Markup.escape_text(keys[i].fpr[0:16]))</span>");
|
list_store.set(iter, 0, @"$(Markup.escape_text(keys[i].uids[0].uid))\n<span font_family='monospace' font='8'>$(markup_colorize_id(keys[i].fpr, true))</span><span font='8'> </span>");
|
||||||
list_store.set(iter, 1, keys[i].fpr);
|
list_store.set(iter, 1, keys[i].fpr);
|
||||||
if (keys[i].fpr == plugin.db.get_account_key(current_account)) {
|
if (keys[i].fpr == plugin.db.get_account_key(current_account)) {
|
||||||
set_label_active(iter, i + 1);
|
set_label_active(iter, i + 1);
|
||||||
|
@ -139,7 +139,7 @@ private class AccountSettingsWidget : Stack, Plugins.AccountSettingsWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
private string build_markup_string(string primary, string secondary) {
|
private string build_markup_string(string primary, string secondary) {
|
||||||
return @"$(Markup.escape_text(primary))\n<span font='8'>$(Markup.escape_text(secondary))</span>";
|
return @"$(Markup.escape_text(primary))\n<span font='8'>$secondary</span>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
plugins/openpgp/src/contact_details_provider.vala
Normal file
34
plugins/openpgp/src/contact_details_provider.vala
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
using Gtk;
|
||||||
|
|
||||||
|
using Dino.Entities;
|
||||||
|
|
||||||
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
|
public class ContactDetailsProvider : Plugins.ContactDetailsProvider {
|
||||||
|
public override string id { get { return "pgp_info"; } }
|
||||||
|
|
||||||
|
private StreamInteractor stream_interactor;
|
||||||
|
|
||||||
|
public ContactDetailsProvider(StreamInteractor stream_interactor) {
|
||||||
|
this.stream_interactor = stream_interactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void populate(Conversation conversation, Plugins.ContactDetails contact_details) {
|
||||||
|
if (conversation.type_ == Conversation.Type.CHAT) {
|
||||||
|
string? key_id = stream_interactor.get_module(Manager.IDENTITY).get_key_id(conversation.account, conversation.counterpart);
|
||||||
|
if (key_id != null) {
|
||||||
|
Gee.List<GPG.Key> keys = GPGHelper.get_keylist(key_id);
|
||||||
|
if (keys.size > 0) {
|
||||||
|
Label label = new Label(markup_colorize_id(keys[0].fpr, true)) { use_markup=true, justify=Justification.RIGHT, visible=true };
|
||||||
|
contact_details.add(_("Encryption"), _("OpenPGP"), "", label);
|
||||||
|
} else {
|
||||||
|
string s = _("Key not in keychain") + "\n" + markup_colorize_id(key_id, false);
|
||||||
|
Label label = new Label(s) { use_markup=true, justify=Justification.RIGHT, visible=true };
|
||||||
|
contact_details.add(_("Encryption"), _("OpenPGP"), "", label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,7 +19,8 @@ private class EncryptionListEntry : Plugins.EncryptionListEntry, Object {
|
||||||
}}
|
}}
|
||||||
|
|
||||||
public bool can_encrypt(Entities.Conversation conversation) {
|
public bool can_encrypt(Entities.Conversation conversation) {
|
||||||
return stream_interactor.get_module(Manager.IDENTITY).get_key_id(conversation.account, conversation.counterpart) != null;
|
string? key_id = stream_interactor.get_module(Manager.IDENTITY).get_key_id(conversation.account, conversation.counterpart);
|
||||||
|
return key_id != null && GPGHelper.get_keylist(key_id).size > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,22 +7,25 @@ extern const string LOCALE_INSTALL_DIR;
|
||||||
|
|
||||||
namespace Dino.Plugins.OpenPgp {
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
public class Plugin : Plugins.RootInterface, Object {
|
public class Plugin : Plugins.RootInterface, Object {
|
||||||
public Dino.Application app;
|
public Dino.Application app;
|
||||||
public Database db;
|
public Database db;
|
||||||
public HashMap<Account, Module> modules = new HashMap<Account, Module>(Account.hash_func, Account.equals_func);
|
public HashMap<Account, Module> modules = new HashMap<Account, Module>(Account.hash_func, Account.equals_func);
|
||||||
|
|
||||||
private EncryptionListEntry list_entry;
|
private EncryptionListEntry list_entry;
|
||||||
private AccountSettingsEntry settings_entry;
|
private AccountSettingsEntry settings_entry;
|
||||||
|
private ContactDetailsProvider contact_details_provider;
|
||||||
|
|
||||||
public void registered(Dino.Application app) {
|
public void registered(Dino.Application app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.db = new Database(Path.build_filename(Application.get_storage_dir(), "pgp.db"));
|
this.db = new Database(Path.build_filename(Application.get_storage_dir(), "pgp.db"));
|
||||||
this.list_entry = new EncryptionListEntry(app.stream_interaction);
|
this.list_entry = new EncryptionListEntry(app.stream_interaction);
|
||||||
this.settings_entry = new AccountSettingsEntry(this);
|
this.settings_entry = new AccountSettingsEntry(this);
|
||||||
|
this.contact_details_provider = new ContactDetailsProvider(app.stream_interaction);
|
||||||
|
|
||||||
app.plugin_registry.register_encryption_list_entry(list_entry);
|
app.plugin_registry.register_encryption_list_entry(list_entry);
|
||||||
app.plugin_registry.register_account_settings_entry(settings_entry);
|
app.plugin_registry.register_account_settings_entry(settings_entry);
|
||||||
|
app.plugin_registry.register_contact_details_entry(contact_details_provider);
|
||||||
app.stream_interaction.module_manager.initialize_account_modules.connect(on_initialize_account_modules);
|
app.stream_interaction.module_manager.initialize_account_modules.connect(on_initialize_account_modules);
|
||||||
|
|
||||||
Manager.start(app.stream_interaction, db);
|
Manager.start(app.stream_interaction, db);
|
||||||
|
@ -37,6 +40,6 @@ namespace Dino.Plugins.OpenPgp {
|
||||||
this.modules[account] = module;
|
this.modules[account] = module;
|
||||||
modules.add(module);
|
modules.add(module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
50
plugins/openpgp/src/util.vala
Normal file
50
plugins/openpgp/src/util.vala
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
using Gtk;
|
||||||
|
|
||||||
|
using Dino.Entities;
|
||||||
|
|
||||||
|
namespace Dino.Plugins.OpenPgp {
|
||||||
|
|
||||||
|
/* Adapted from OpenKeychain */
|
||||||
|
public static string markup_colorize_id(string s, bool is_fingerprint) {
|
||||||
|
string markup = is_fingerprint ? "" : "0x";
|
||||||
|
for (int i = 0; i < s.length; i += 4) {
|
||||||
|
string four_chars = s.substring(i, 4).down();
|
||||||
|
|
||||||
|
int raw = (int) four_chars.to_long(null, 16);
|
||||||
|
uint8[] bytes = {(uint8) ((raw >> 8) & 0xff - 128), (uint8) (raw & 0xff - 128)};
|
||||||
|
|
||||||
|
Checksum checksum = new Checksum(ChecksumType.SHA1);
|
||||||
|
checksum.update(bytes, bytes.length);
|
||||||
|
uint8[] digest = new uint8[20];
|
||||||
|
size_t len = 20;
|
||||||
|
checksum.get_digest(digest, ref len);
|
||||||
|
|
||||||
|
uint8 r = digest[0];
|
||||||
|
uint8 g = digest[1];
|
||||||
|
uint8 b = digest[2];
|
||||||
|
|
||||||
|
if (r == 0 && g == 0 && b == 0) r = g = b = 1;
|
||||||
|
|
||||||
|
double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||||
|
|
||||||
|
if (brightness < 80) {
|
||||||
|
double factor = 80.0 / brightness;
|
||||||
|
r = uint8.min(255, (uint8) (r * factor));
|
||||||
|
g = uint8.min(255, (uint8) (g * factor));
|
||||||
|
b = uint8.min(255, (uint8) (b * factor));
|
||||||
|
|
||||||
|
} else if (brightness > 180) {
|
||||||
|
double factor = 180.0 / brightness;
|
||||||
|
r = (uint8) (r * factor);
|
||||||
|
g = (uint8) (g * factor);
|
||||||
|
b = (uint8) (b * factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 4 * 5) markup += "\n";
|
||||||
|
markup += @"<span foreground=\"$("#%02x%02x%02x".printf(r, g, b))\">$four_chars</span>";
|
||||||
|
if (is_fingerprint) markup += " ";
|
||||||
|
}
|
||||||
|
return "<span font_family='monospace' font='8'>" + markup + "</span>";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue