Skip to content

Commit 652a700

Browse files
committed
api!: Contact::get_color: Ensure that own key exists before returning self-color (#7374)
Otherwise gray is returned and we don't want any UIs displaying it. Keypair generation is done in `get_color()` instead of `get_by_id_optional()` to avoid breaking Core tests on key import.
1 parent 7fef812 commit 652a700

File tree

9 files changed

+57
-19
lines changed

9 files changed

+57
-19
lines changed

deltachat-ffi/src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4240,7 +4240,16 @@ pub unsafe extern "C" fn dc_contact_get_color(contact: *mut dc_contact_t) -> u32
42404240
return 0;
42414241
}
42424242
let ffi_contact = &*contact;
4243-
ffi_contact.contact.get_color()
4243+
let ctx = &*ffi_contact.context;
4244+
block_on(async move {
4245+
ffi_contact
4246+
.contact
4247+
.get_color(ctx)
4248+
.await
4249+
.context("Contact::get_color()")
4250+
.log_err(ctx)
4251+
.unwrap_or(0)
4252+
})
42444253
}
42454254

42464255
#[no_mangle]

deltachat-jsonrpc/src/api/types/account.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ impl Account {
3232
let addr = ctx.get_config(Config::Addr).await?;
3333
let profile_image = ctx.get_config(Config::Selfavatar).await?;
3434
let color = color_int_to_hex_string(
35-
Contact::get_by_id(ctx, ContactId::SELF).await?.get_color(),
35+
Contact::get_by_id(ctx, ContactId::SELF)
36+
.await?
37+
.get_color(ctx)
38+
.await?,
3639
);
3740
let private_tag = ctx.get_config(Config::PrivateTag).await?;
3841
Ok(Account::Configured {

deltachat-jsonrpc/src/api/types/contact.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl ContactObject {
9090

9191
Ok(ContactObject {
9292
address: contact.get_addr().to_owned(),
93-
color: color_int_to_hex_string(contact.get_color()),
93+
color: color_int_to_hex_string(contact.get_color(context).await?),
9494
auth_name: contact.get_authname().to_owned(),
9595
status: contact.get_status().to_owned(),
9696
display_name: contact.get_display_name().to_owned(),

deltachat-jsonrpc/src/api/types/message.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ impl MessageObject {
160160
message_id: quote.get_id().to_u32(),
161161
chat_id: quote.get_chat_id().to_u32(),
162162
author_display_name: quote_author.get_display_name().to_owned(),
163-
author_display_color: color_int_to_hex_string(quote_author.get_color()),
163+
author_display_color: color_int_to_hex_string(
164+
quote_author.get_color(context).await?,
165+
),
164166
override_sender_name: quote.get_override_sender_name(),
165167
image: if quote.get_viewtype() == Viewtype::Image
166168
|| quote.get_viewtype() == Viewtype::Gif
@@ -565,7 +567,7 @@ impl MessageSearchResult {
565567
id: msg_id.to_u32(),
566568
author_profile_image: profile_image,
567569
author_name,
568-
author_color: color_int_to_hex_string(sender.get_color()),
570+
author_color: color_int_to_hex_string(sender.get_color(context).await?),
569571
author_id: sender.id.to_u32(),
570572
chat_id: chat.id.to_u32(),
571573
chat_name: chat.get_name().to_owned(),

src/chat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1578,7 +1578,7 @@ impl Chat {
15781578
let contacts = get_chat_contacts(context, self.id).await?;
15791579
if let Some(contact_id) = contacts.first() {
15801580
if let Ok(contact) = Contact::get_by_id(context, *contact_id).await {
1581-
color = contact.get_color();
1581+
color = contact.get_color(context).await?;
15821582
}
15831583
}
15841584
} else if !self.grpid.is_empty() {

src/contact.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1574,9 +1574,14 @@ impl Contact {
15741574
}
15751575

15761576
/// Returns a color for the contact.
1577-
/// See [`self::get_color`].
1578-
pub fn get_color(&self) -> u32 {
1579-
get_color(self.id == ContactId::SELF, &self.addr, &self.fingerprint())
1577+
/// For self-contact this generates own keypair if it doesn't exist yet.
1578+
/// See also [`self::get_color`].
1579+
pub async fn get_color(&self, context: &Context) -> Result<u32> {
1580+
let mut fpr = self.fingerprint();
1581+
if fpr.is_none() && self.id == ContactId::SELF {
1582+
fpr = Some(load_self_public_key(context).await?.dc_fingerprint());
1583+
}
1584+
Ok(get_color(self.id == ContactId::SELF, &self.addr, &fpr))
15801585
}
15811586

15821587
/// Gets the contact's status.

src/contact/contact_tests.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -759,32 +759,51 @@ async fn test_lookup_id_by_addr() {
759759
async fn test_contact_get_color() -> Result<()> {
760760
let t = TestContext::new().await;
761761
let contact_id = Contact::create(&t, "name", "[email protected]").await?;
762-
let color1 = Contact::get_by_id(&t, contact_id).await?.get_color();
762+
let color1 = Contact::get_by_id(&t, contact_id)
763+
.await?
764+
.get_color(&t)
765+
.await?;
763766
assert_eq!(color1, 0x4844e2);
764767

765768
let t = TestContext::new().await;
766769
let contact_id = Contact::create(&t, "prename name", "[email protected]").await?;
767-
let color2 = Contact::get_by_id(&t, contact_id).await?.get_color();
770+
let color2 = Contact::get_by_id(&t, contact_id)
771+
.await?
772+
.get_color(&t)
773+
.await?;
768774
assert_eq!(color2, color1);
769775

770776
let t = TestContext::new().await;
771777
let contact_id = Contact::create(&t, "Name", "[email protected]").await?;
772-
let color3 = Contact::get_by_id(&t, contact_id).await?.get_color();
778+
let color3 = Contact::get_by_id(&t, contact_id)
779+
.await?
780+
.get_color(&t)
781+
.await?;
773782
assert_eq!(color3, color1);
774783
Ok(())
775784
}
776785

777786
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
778-
async fn test_self_color_vs_key() -> Result<()> {
787+
async fn test_self_color() -> Result<()> {
779788
let mut tcm = TestContextManager::new();
780789
let t = &tcm.unconfigured().await;
781790
t.configure_addr("[email protected]").await;
782791
assert!(t.is_configured().await?);
783-
let color = Contact::get_by_id(t, ContactId::SELF).await?.get_color();
784-
assert_eq!(color, 0x808080);
792+
let color = Contact::get_by_id(t, ContactId::SELF)
793+
.await?
794+
.get_color(t)
795+
.await?;
796+
assert_ne!(color, 0x808080);
785797
get_securejoin_qr(t, None).await?;
786-
let color1 = Contact::get_by_id(t, ContactId::SELF).await?.get_color();
787-
assert_ne!(color1, color);
798+
let color1 = Contact::get_by_id(t, ContactId::SELF)
799+
.await?
800+
.get_color(t)
801+
.await?;
802+
assert_eq!(color1, color);
803+
804+
let bob = &tcm.bob().await;
805+
let contact = bob.add_or_lookup_contact(t).await;
806+
assert_eq!(contact.get_color(bob).await?, color);
788807
Ok(())
789808
}
790809

src/qr_code_generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ async fn self_info(context: &Context) -> Result<(Option<Vec<u8>>, String, String
171171
None => contact.get_addr().to_string(),
172172
};
173173
let addr = contact.get_addr().to_string();
174-
let color = color_int_to_hex_string(contact.get_color());
174+
let color = color_int_to_hex_string(contact.get_color(context).await?);
175175
Ok((avatar, displayname, addr, color))
176176
}
177177

src/webxdc/maps_integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ pub(crate) async fn intercept_get_updates(
112112
hash_map::Entry::Vacant(e) => {
113113
let contact = Contact::get_by_id(context, location.contact_id).await?;
114114
let name = contact.get_display_name().to_string();
115-
let color = color_int_to_hex_string(contact.get_color());
115+
let color = color_int_to_hex_string(contact.get_color(context).await?);
116116
e.insert((name, color)).clone()
117117
}
118118
hash_map::Entry::Occupied(e) => e.get().clone(),

0 commit comments

Comments
 (0)