Merge branch 'master' into encrypted_attachments

master
Damir Jelić 2020-09-15 09:31:46 +02:00
commit a60f60bd7d
8 changed files with 89 additions and 106 deletions

View File

@ -15,12 +15,10 @@ struct UserProfile {
/// This function calls the GET profile endpoint /// This function calls the GET profile endpoint
/// Spec: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-profile-userid /// Spec: https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-profile-userid
/// Ruma: https://docs.rs/ruma-client-api/0.9.0/ruma_client_api/r0/profile/get_profile/index.html /// Ruma: https://docs.rs/ruma-client-api/0.9.0/ruma_client_api/r0/profile/get_profile/index.html
async fn get_profile(client: Client, mxid: UserId) -> MatrixResult<UserProfile> { async fn get_profile(client: Client, mxid: &UserId) -> MatrixResult<UserProfile> {
// First construct the request you want to make // First construct the request you want to make
// See https://docs.rs/ruma-client-api/0.9.0/ruma_client_api/index.html for all available Endpoints // See https://docs.rs/ruma-client-api/0.9.0/ruma_client_api/index.html for all available Endpoints
let request = profile::get_profile::Request { let request = profile::get_profile::Request::new(mxid);
user_id: mxid.clone(),
};
// Start the request using matrix_sdk::Client::send // Start the request using matrix_sdk::Client::send
let resp = client.send(request).await?; let resp = client.send(request).await?;
@ -72,7 +70,7 @@ async fn main() -> Result<(), matrix_sdk::Error> {
let client = login(homeserver_url, &username, &password).await?; let client = login(homeserver_url, &username, &password).await?;
let user_id = UserId::try_from(username).expect("Couldn't parse the MXID"); let user_id = UserId::try_from(username).expect("Couldn't parse the MXID");
let profile = get_profile(client, user_id).await?; let profile = get_profile(client, &user_id).await?;
println!("{:#?}", profile); println!("{:#?}", profile);
Ok(()) Ok(())
} }

View File

@ -13,6 +13,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#[cfg(feature = "encryption")]
use std::{collections::BTreeMap, io::Write, path::PathBuf};
use std::{ use std::{
collections::HashMap, collections::HashMap,
convert::{TryFrom, TryInto}, convert::{TryFrom, TryInto},
@ -23,8 +25,6 @@ use std::{
result::Result as StdResult, result::Result as StdResult,
sync::Arc, sync::Arc,
}; };
#[cfg(feature = "encryption")]
use std::{io::Write, path::PathBuf};
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use dashmap::DashMap; use dashmap::DashMap;
@ -85,6 +85,7 @@ use matrix_sdk_common::{
Request as RumaToDeviceRequest, Response as ToDeviceResponse, Request as RumaToDeviceRequest, Response as ToDeviceResponse,
}, },
}, },
identifiers::DeviceIdBox,
locks::Mutex, locks::Mutex,
}; };
@ -496,12 +497,15 @@ impl Client {
) -> Result<login::Response> { ) -> Result<login::Response> {
info!("Logging in to {} as {:?}", self.homeserver, user); info!("Logging in to {} as {:?}", self.homeserver, user);
let request = login::Request { let request = assign!(
user: login::UserInfo::MatrixId(user), login::Request::new(
login_info: login::LoginInfo::Password { password }, login::UserInfo::MatrixId(user),
device_id: device_id.map(|d| d.into()), login::LoginInfo::Password { password },
initial_device_display_name, ), {
}; device_id: device_id.map(|d| d.into()),
initial_device_display_name,
}
);
let response = self.send(request).await?; let response = self.send(request).await?;
self.base_client.receive_login_response(&response).await?; self.base_client.receive_login_response(&response).await?;
@ -741,11 +745,11 @@ impl Client {
) -> Result<get_public_rooms::Response> { ) -> Result<get_public_rooms::Response> {
let limit = limit.map(|n| UInt::try_from(n).ok()).flatten(); let limit = limit.map(|n| UInt::try_from(n).ok()).flatten();
let request = get_public_rooms::Request { let request = assign!(get_public_rooms::Request::new(), {
limit, limit,
since, since,
server, server,
}; });
self.send(request).await self.send(request).await
} }
@ -896,11 +900,8 @@ impl Client {
room_id: &RoomId, room_id: &RoomId,
typing: impl Into<Typing>, typing: impl Into<Typing>,
) -> Result<TypingResponse> { ) -> Result<TypingResponse> {
let request = TypingRequest { let user_id = self.user_id().await.ok_or(Error::AuthenticationRequired)?;
room_id: room_id.clone(), let request = TypingRequest::new(&user_id, room_id, typing.into());
user_id: self.user_id().await.ok_or(Error::AuthenticationRequired)?,
state: typing.into(),
};
self.send(request).await self.send(request).await
} }
@ -919,11 +920,8 @@ impl Client {
room_id: &RoomId, room_id: &RoomId,
event_id: &EventId, event_id: &EventId,
) -> Result<create_receipt::Response> { ) -> Result<create_receipt::Response> {
let request = create_receipt::Request { let request =
room_id: room_id.clone(), create_receipt::Request::new(room_id, create_receipt::ReceiptType::Read, event_id);
event_id: event_id.clone(),
receipt_type: create_receipt::ReceiptType::Read,
};
self.send(request).await self.send(request).await
} }
@ -1116,9 +1114,7 @@ impl Client {
encryptor.read_to_end(&mut data).unwrap(); encryptor.read_to_end(&mut data).unwrap();
let keys = encryptor.finish(); let keys = encryptor.finish();
let upload = self let upload = self.upload("application/octet-stream", data).await?;
.upload("application/octet-stream".to_owned(), data, None)
.await?;
let content = EncryptedFile { let content = EncryptedFile {
url: upload.content_uri, url: upload.content_uri,
@ -1143,9 +1139,7 @@ impl Client {
let mut data = Vec::new(); let mut data = Vec::new();
reader.read_to_end(&mut data).unwrap(); reader.read_to_end(&mut data).unwrap();
let upload = self let upload = self.upload("application/octet-stream", data).await?;
.upload("application/octet-stream".to_owned(), data, None)
.await?;
let content = AnyMessageEventContent::RoomMessage(MessageEventContent::File( let content = AnyMessageEventContent::RoomMessage(MessageEventContent::File(
FileMessageEventContent { FileMessageEventContent {
@ -1160,17 +1154,8 @@ impl Client {
self.room_send(room_id, content, txn_id).await self.room_send(room_id, content, txn_id).await
} }
async fn upload( async fn upload(&self, content_type: &str, data: Vec<u8>) -> Result<create_content::Response> {
&self, let request = create_content::Request::new(content_type, data);
content_type: String,
data: Vec<u8>,
filename: Option<String>,
) -> Result<create_content::Response> {
let request = create_content::Request {
content_type,
file: data,
filename,
};
self.send(request).await self.send(request).await
} }
@ -1202,9 +1187,8 @@ impl Client {
/// // First construct the request you want to make /// // First construct the request you want to make
/// // See https://docs.rs/ruma-client-api/latest/ruma_client_api/index.html /// // See https://docs.rs/ruma-client-api/latest/ruma_client_api/index.html
/// // for all available Endpoints /// // for all available Endpoints
/// let request = profile::get_profile::Request { /// let user_id = user_id!("@example:localhost");
/// user_id: user_id!("@example:localhost"), /// let request = profile::get_profile::Request::new(&user_id);
/// };
/// ///
/// // Start the request using Client::send() /// // Start the request using Client::send()
/// let response = client.send(request).await.unwrap(); /// let response = client.send(request).await.unwrap();
@ -1224,11 +1208,8 @@ impl Client {
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
async fn send_to_device(&self, request: ToDeviceRequest) -> Result<ToDeviceResponse> { async fn send_to_device(&self, request: ToDeviceRequest) -> Result<ToDeviceResponse> {
let txn_id_string = request.txn_id_string(); let txn_id_string = request.txn_id_string();
let request = RumaToDeviceRequest { let request =
event_type: request.event_type, RumaToDeviceRequest::new(request.event_type, &txn_id_string, request.messages);
txn_id: &txn_id_string,
messages: request.messages,
};
self.send(request).await self.send(request).await
} }
@ -1257,7 +1238,7 @@ impl Client {
/// # }); /// # });
/// ``` /// ```
pub async fn devices(&self) -> Result<get_devices::Response> { pub async fn devices(&self) -> Result<get_devices::Response> {
let request = get_devices::Request {}; let request = get_devices::Request::new();
self.send(request).await self.send(request).await
} }
@ -1377,7 +1358,10 @@ impl Client {
for r in self.base_client.outgoing_requests().await { for r in self.base_client.outgoing_requests().await {
match r.request() { match r.request() {
OutgoingRequests::KeysQuery(request) => { OutgoingRequests::KeysQuery(request) => {
if let Err(e) = self.keys_query(r.request_id(), request).await { if let Err(e) = self
.keys_query(r.request_id(), request.device_keys.clone())
.await
{
warn!("Error while querying device keys {:?}", e); warn!("Error while querying device keys {:?}", e);
} }
} }
@ -1524,13 +1508,9 @@ impl Client {
async fn keys_query( async fn keys_query(
&self, &self,
request_id: &Uuid, request_id: &Uuid,
request: &get_keys::IncomingRequest, device_keys: BTreeMap<UserId, Vec<DeviceIdBox>>,
) -> Result<get_keys::Response> { ) -> Result<get_keys::Response> {
let request = get_keys::Request { let request = assign!(get_keys::Request::new(), { device_keys });
timeout: None,
device_keys: request.device_keys.clone(),
token: None,
};
let response = self.send(request).await?; let response = self.send(request).await?;
self.base_client self.base_client

View File

@ -62,11 +62,8 @@ impl Device {
/// ``` /// ```
pub async fn start_verification(&self) -> Result<Sas> { pub async fn start_verification(&self) -> Result<Sas> {
let (sas, request) = self.inner.start_verification().await?; let (sas, request) = self.inner.start_verification().await?;
let request = ToDeviceRequest { let txn_id_string = request.txn_id_string();
event_type: request.event_type, let request = ToDeviceRequest::new(request.event_type, &txn_id_string, request.messages);
txn_id: &request.txn_id.to_string(),
messages: request.messages,
};
self.http_client.send(request).await?; self.http_client.send(request).await?;

View File

@ -28,11 +28,8 @@ impl Sas {
/// Accept the interactive verification flow. /// Accept the interactive verification flow.
pub async fn accept(&self) -> Result<()> { pub async fn accept(&self) -> Result<()> {
if let Some(req) = self.inner.accept() { if let Some(req) = self.inner.accept() {
let request = ToDeviceRequest { let txn_id_string = req.txn_id_string();
event_type: req.event_type, let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
txn_id: &req.txn_id.to_string(),
messages: req.messages,
};
self.http_client.send(request).await?; self.http_client.send(request).await?;
} }
@ -42,11 +39,8 @@ impl Sas {
/// Confirm that the short auth strings match on both sides. /// Confirm that the short auth strings match on both sides.
pub async fn confirm(&self) -> Result<()> { pub async fn confirm(&self) -> Result<()> {
if let Some(req) = self.inner.confirm().await? { if let Some(req) = self.inner.confirm().await? {
let request = ToDeviceRequest { let txn_id_string = req.txn_id_string();
event_type: req.event_type, let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
txn_id: &req.txn_id.to_string(),
messages: req.messages,
};
self.http_client.send(request).await?; self.http_client.send(request).await?;
} }
@ -57,11 +51,8 @@ impl Sas {
/// Cancel the interactive verification flow. /// Cancel the interactive verification flow.
pub async fn cancel(&self) -> Result<()> { pub async fn cancel(&self) -> Result<()> {
if let Some(req) = self.inner.cancel() { if let Some(req) = self.inner.cancel() {
let request = ToDeviceRequest { let txn_id_string = req.txn_id_string();
event_type: req.event_type, let request = ToDeviceRequest::new(req.event_type, &txn_id_string, req.messages);
txn_id: &req.txn_id.to_string(),
messages: req.messages,
};
self.http_client.send(request).await?; self.http_client.send(request).await?;
} }

View File

@ -18,7 +18,7 @@ js_int = "0.1.9"
[dependencies.ruma] [dependencies.ruma]
version = "0.0.1" version = "0.0.1"
git = "https://github.com/ruma/ruma" git = "https://github.com/ruma/ruma"
rev = "409fbcc9d745fb7290327cb7f5defc714229ab30" rev = "4a9b1aeb3c87bd8574391d7084ec5bf109f7d363"
features = ["client-api", "unstable-pre-spec"] features = ["client-api", "unstable-pre-spec"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]

View File

@ -44,5 +44,7 @@ pub use identities::{
pub use machine::OlmMachine; pub use machine::OlmMachine;
pub(crate) use olm::Account; pub(crate) use olm::Account;
pub use olm::EncryptionSettings; pub use olm::EncryptionSettings;
pub use requests::{IncomingResponse, OutgoingRequest, OutgoingRequests, ToDeviceRequest}; pub use requests::{
IncomingResponse, KeysQueryRequest, OutgoingRequest, OutgoingRequests, ToDeviceRequest,
};
pub use verification::Sas; pub use verification::Sas;

View File

@ -30,12 +30,13 @@ use matrix_sdk_common::{
api::r0::{ api::r0::{
keys::{ keys::{
claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse}, claim_keys::{Request as KeysClaimRequest, Response as KeysClaimResponse},
get_keys::{IncomingRequest as KeysQueryRequest, Response as KeysQueryResponse}, get_keys::Response as KeysQueryResponse,
upload_keys, upload_keys,
}, },
sync::sync_events::Response as SyncResponse, sync::sync_events::Response as SyncResponse,
to_device::DeviceIdOrAllDevices, to_device::DeviceIdOrAllDevices,
}, },
assign,
encryption::DeviceKeys, encryption::DeviceKeys,
events::{ events::{
forwarded_room_key::ForwardedRoomKeyEventContent, room::encrypted::EncryptedEventContent, forwarded_room_key::ForwardedRoomKeyEventContent, room::encrypted::EncryptedEventContent,
@ -60,7 +61,7 @@ use super::{
Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys, Account, EncryptionSettings, ExportedRoomKey, GroupSessionKey, IdentityKeys,
InboundGroupSession, OlmMessage, OutboundGroupSession, InboundGroupSession, OlmMessage, OutboundGroupSession,
}, },
requests::{IncomingResponse, OutgoingRequest, ToDeviceRequest}, requests::{IncomingResponse, KeysQueryRequest, OutgoingRequest, ToDeviceRequest},
store::{CryptoStore, MemoryStore, Result as StoreResult}, store::{CryptoStore, MemoryStore, Result as StoreResult},
verification::{Sas, VerificationMachine}, verification::{Sas, VerificationMachine},
}; };
@ -415,10 +416,9 @@ impl OlmMachine {
} else { } else {
Ok(Some(( Ok(Some((
Uuid::new_v4(), Uuid::new_v4(),
KeysClaimRequest { assign!(KeysClaimRequest::new(missing), {
timeout: Some(OlmMachine::KEY_CLAIM_TIMEOUT), timeout: Some(OlmMachine::KEY_CLAIM_TIMEOUT),
one_time_keys: missing, }),
},
))) )))
} }
} }
@ -700,11 +700,7 @@ impl OlmMachine {
/// [`OlmMachine`]: struct.OlmMachine.html /// [`OlmMachine`]: struct.OlmMachine.html
async fn keys_for_upload(&self) -> Option<upload_keys::Request> { async fn keys_for_upload(&self) -> Option<upload_keys::Request> {
let (device_keys, one_time_keys) = self.account.keys_for_upload().await?; let (device_keys, one_time_keys) = self.account.keys_for_upload().await?;
Some(assign!(upload_keys::Request::new(), { device_keys, one_time_keys }))
Some(upload_keys::Request {
device_keys,
one_time_keys,
})
} }
/// Try to decrypt an Olm message. /// Try to decrypt an Olm message.
@ -1428,11 +1424,7 @@ impl OlmMachine {
device_keys.insert(user, Vec::new()); device_keys.insert(user, Vec::new());
} }
Some(KeysQueryRequest { Some(KeysQueryRequest::new(device_keys))
timeout: None,
device_keys,
token: None,
})
} }
} }
@ -1778,10 +1770,7 @@ pub(crate) mod test {
let mut one_time_keys = BTreeMap::new(); let mut one_time_keys = BTreeMap::new();
one_time_keys.insert(bob.user_id.clone(), bob_keys); one_time_keys.insert(bob.user_id.clone(), bob_keys);
let response = claim_keys::Response { let response = claim_keys::Response::new(one_time_keys);
failures: BTreeMap::new(),
one_time_keys,
};
alice.receive_keys_claim_response(&response).await.unwrap(); alice.receive_keys_claim_response(&response).await.unwrap();
@ -2052,10 +2041,7 @@ pub(crate) mod test {
let mut one_time_keys = BTreeMap::new(); let mut one_time_keys = BTreeMap::new();
one_time_keys.insert(bob_machine.user_id.clone(), bob_keys); one_time_keys.insert(bob_machine.user_id.clone(), bob_keys);
let response = claim_keys::Response { let response = claim_keys::Response::new(one_time_keys);
failures: BTreeMap::new(),
one_time_keys,
};
alice_machine alice_machine
.receive_keys_claim_response(&response) .receive_keys_claim_response(&response)

View File

@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::{collections::BTreeMap, sync::Arc}; use std::{collections::BTreeMap, sync::Arc, time::Duration};
use matrix_sdk_common::{ use matrix_sdk_common::{
api::r0::{ api::r0::{
keys::{ keys::{
claim_keys::Response as KeysClaimResponse, claim_keys::Response as KeysClaimResponse,
get_keys::{IncomingRequest as KeysQueryRequest, Response as KeysQueryResponse}, get_keys::Response as KeysQueryResponse,
upload_keys::{Request as KeysUploadRequest, Response as KeysUploadResponse}, upload_keys::{Request as KeysUploadRequest, Response as KeysUploadResponse},
}, },
to_device::{send_event_to_device::Response as ToDeviceResponse, DeviceIdOrAllDevices}, to_device::{send_event_to_device::Response as ToDeviceResponse, DeviceIdOrAllDevices},
}, },
events::EventType, events::EventType,
identifiers::UserId, identifiers::{DeviceIdBox, UserId},
uuid::Uuid, uuid::Uuid,
}; };
@ -56,6 +56,35 @@ impl ToDeviceRequest {
} }
} }
/// Customized version of `ruma_client_api::r0::keys::get_keys::Request`, without any references.
#[derive(Clone, Debug)]
pub struct KeysQueryRequest {
/// The time (in milliseconds) to wait when downloading keys from remote
/// servers. 10 seconds is the recommended default.
pub timeout: Option<Duration>,
/// The keys to be downloaded. An empty list indicates all devices for
/// the corresponding user.
pub device_keys: BTreeMap<UserId, Vec<DeviceIdBox>>,
/// If the client is fetching keys as a result of a device update
/// received in a sync request, this should be the 'since' token of that
/// sync request, or any later sync token. This allows the server to
/// ensure its response contains the keys advertised by the notification
/// in that sync.
pub token: Option<String>,
}
impl KeysQueryRequest {
pub(crate) fn new(device_keys: BTreeMap<UserId, Vec<DeviceIdBox>>) -> Self {
Self {
timeout: None,
device_keys,
token: None,
}
}
}
/// Enum over the different outgoing requests we can have. /// Enum over the different outgoing requests we can have.
#[derive(Debug)] #[derive(Debug)]
pub enum OutgoingRequests { pub enum OutgoingRequests {