Skip to content

Commit

Permalink
Improve name resolution (#167)
Browse files Browse the repository at this point in the history
Name resolution from profile (via signal service) was broken due to
fetching of unversioned profile in libsignal-service. We patched the
library. The patch is not yet upstreamed and used from the main branch
due to the issue [62].

[62]: whisperfish/presage#62
  • Loading branch information
boxdot authored Jul 10, 2022
1 parent 13c2cab commit c0f7e39
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 37 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@

### Changed

- Fixed receiving direct messages sent from another device
- Replace log4rs with tracing ([#158], [#160])
- Display date only once per day ([#164])

### Fixed

- Fixed receiving direct messages sent from another device ([#162])
- Improve name resolution ([#167])

[#158]: https://github.com/boxdot/gurk-rs/pull/158
[#160]: https://github.com/boxdot/gurk-rs/pull/160
[#162]: https://github.com/boxdot/gurk-rs/pull/162
[#167]: https://github.com/boxdot/gurk-rs/pull/167

## 0.2.4

Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ debug = 0
lto = "thin"

[dependencies]
presage = { git = "https://github.com/whisperfish/presage.git", rev = "8fcfb65" }
presage = { git = "https://github.com/boxdot/presage.git", rev = "f908e8f" }

anyhow = "1.0.40"
async-trait = "0.1.51"
Expand Down
70 changes: 38 additions & 32 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,15 @@ impl App {
self.storage.save_app_data(&self.data)
}

// Resolves name of a user by their id
//
// The resolution is done in the following way:
//
// 1. It's us => name from config
// 2. User id is in presage's signal manager (that is, it is a known contact from our address
// book) => use it,
// 3. User id is in the gurk's user name table (custom name) => use it,
// 4. give up with "Unknown User"
pub fn name_by_id(&self, id: Uuid) -> String {
if self.user_id == id {
// it's me
Expand Down Expand Up @@ -1366,7 +1375,7 @@ impl App {
profile_keys,
} = self.signal_manager.resolve_group(master_key).await?;

self.try_ensure_users_are_known(
self.ensure_users_are_known(
group_data
.members
.iter()
Expand All @@ -1387,7 +1396,7 @@ impl App {
profile_keys,
} = self.signal_manager.resolve_group(master_key).await?;

self.try_ensure_users_are_known(
self.ensure_users_are_known(
group_data
.members
.iter()
Expand All @@ -1409,8 +1418,18 @@ impl App {
}

async fn ensure_user_is_known(&mut self, uuid: Uuid, profile_key: ProfileKey) {
if !self.try_ensure_user_is_known(uuid, profile_key).await {
let name = self
// is_known <=>
// * in names, or
// * is not a phone numbers, or
// * is not their uuid
let is_known = self
.data
.names
.get(&uuid)
.filter(|name| !util::is_phone_number(name) && Uuid::from_str(name) != Ok(uuid))
.is_some();
if !is_known {
if let Some(name) = self
.signal_manager
.contact_by_id(uuid)
.ok()
Expand All @@ -1419,44 +1438,31 @@ impl App {
c.address
.phonenumber
.and_then(|p| Some(p.format().mode(Mode::E164).to_string()))
});
self.data
.names
.insert(uuid, name.unwrap_or_else(|| uuid.to_string()));
}
}

/// Returns `true`, if user name was resolved successfully, otherwise `false`
async fn try_ensure_user_is_known(&mut self, uuid: Uuid, profile_key: ProfileKey) -> bool {
let is_phone_number_or_unknown = self
.data
.names
.get(&uuid)
.map(util::is_phone_number)
.unwrap_or(true);
if is_phone_number_or_unknown {
let name = match profile_key.try_into() {
Ok(key) => {
self.signal_manager
.resolve_name_from_profile(uuid, key)
.await
}
Err(_) => None,
};
if let Some(name) = name {
})
{
// resolved from contact list
self.data.names.insert(uuid, name);
} else if let Some(name) = self
.signal_manager
.resolve_name_from_profile(uuid, profile_key)
.await
{
// resolved from signal service via their profile
self.data.names.insert(uuid, name);
} else {
// failed to resolve
self.data.names.insert(uuid, uuid.to_string());
}
}
self.data.names.contains_key(&uuid)
}

async fn try_ensure_users_are_known(
async fn ensure_users_are_known(
&mut self,
users_with_keys: impl Iterator<Item = (Uuid, ProfileKey)>,
) {
// TODO: Run in parallel
for (uuid, profile_key) in users_with_keys {
self.try_ensure_user_is_known(uuid, profile_key).await;
self.ensure_user_is_known(uuid, profile_key).await;
}
}

Expand Down

0 comments on commit c0f7e39

Please sign in to comment.