Skip to content

Commit

Permalink
shields: Put the Code inside the Colour instead of the Colour inside …
Browse files Browse the repository at this point in the history
…the Code.
  • Loading branch information
pixlwave committed Aug 1, 2024
1 parent 20f2c44 commit 221ace8
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 139 deletions.
4 changes: 2 additions & 2 deletions bindings/matrix-sdk-crypto-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ anyhow = { workspace = true }
futures-util = { workspace = true }
hmac = "0.12.1"
http = { workspace = true }
matrix-sdk-common = { workspace = true }
matrix-sdk-common = { workspace = true, features = ["uniffi"] }
pbkdf2 = "0.12.2"
rand = { workspace = true }
ruma = { workspace = true }
Expand All @@ -35,7 +35,7 @@ sha2 = { workspace = true }
thiserror = { workspace = true }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
# keep in sync with uniffi dependency in matrix-sdk-ffi, and uniffi_bindgen in ffi CI job
uniffi = { workspace = true , features = ["cli"]}
uniffi = { workspace = true, features = ["cli"] }
vodozemac = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }

Expand Down
41 changes: 13 additions & 28 deletions bindings/matrix-sdk-crypto-ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ pub use error::{
use js_int::UInt;
pub use logger::{set_logger, Logger};
pub use machine::{KeyRequestPair, OlmMachine, SignatureVerification};
use matrix_sdk_common::deserialized_responses::{
ShieldState as RustShieldState, ShieldStateColor as RustShieldStateColor,
};
use matrix_sdk_common::deserialized_responses::{ShieldState as RustShieldState, ShieldStateCode};
use matrix_sdk_crypto::{
olm::{IdentityKeys, InboundGroupSession, SenderData, Session},
store::{Changes, CryptoStore, PendingChanges, RoomSettings as RustRoomSettings},
Expand Down Expand Up @@ -728,37 +726,24 @@ pub enum ShieldColor {
#[allow(missing_docs)]
pub struct ShieldState {
color: ShieldColor,
code: Option<ShieldStateCode>,
message: Option<String>,
}

impl From<RustShieldState> for ShieldState {
fn from(value: RustShieldState) -> Self {
match &value {
RustShieldState::AuthenticityNotGuaranteed { color } => {
Self { color: color.into(), message: value.message().map(ToOwned::to_owned) }
}
RustShieldState::UnknownDevice { color } => {
Self { color: color.into(), message: value.message().map(ToOwned::to_owned) }
}
RustShieldState::UnsignedDevice { color } => {
Self { color: color.into(), message: value.message().map(ToOwned::to_owned) }
}
RustShieldState::UnverifiedIdentity { color } => {
Self { color: color.into(), message: value.message().map(ToOwned::to_owned) }
}
RustShieldState::SentInClear { color } => {
Self { color: color.into(), message: value.message().map(ToOwned::to_owned) }
}
RustShieldState::None => Self { color: ShieldColor::None, message: None },
}
}
}

impl From<&RustShieldStateColor> for ShieldColor {
fn from(value: &RustShieldStateColor) -> Self {
match value {
RustShieldStateColor::Red => ShieldColor::Red,
RustShieldStateColor::Grey => ShieldColor::Grey,
RustShieldState::Red { code, message } => Self {
color: ShieldColor::Red,
code: Some(code),
message: Some(message.to_owned()),
},
RustShieldState::Grey { code, message } => Self {
color: ShieldColor::Grey,
code: Some(code),
message: Some(message.to_owned()),
},
RustShieldState::None => Self { color: ShieldColor::None, code: None, message: None },
}
}
}
Expand Down
31 changes: 27 additions & 4 deletions bindings/matrix-sdk-ffi/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use matrix_sdk::{
AttachmentConfig, AttachmentInfo, BaseAudioInfo, BaseFileInfo, BaseImageInfo,
BaseThumbnailInfo, BaseVideoInfo, Thumbnail,
},
deserialized_responses::ShieldState,
deserialized_responses::{ShieldState as RustShieldState, ShieldStateCode},
Error,
};
use matrix_sdk_ui::timeline::{
Expand Down Expand Up @@ -923,9 +923,32 @@ impl From<&matrix_sdk_ui::timeline::EventSendState> for EventSendState {
}
}

#[uniffi::export]
pub fn message_for_shield_state(shield_state: ShieldState) -> Option<String> {
shield_state.message().map(ToOwned::to_owned)
/// Recommended decorations for decrypted messages, representing the message's
/// authenticity properties.
#[derive(uniffi::Enum)]
pub enum ShieldState {
/// A red shield with a tooltip containing the associated message should be
/// presented.
Red { code: ShieldStateCode, message: String },
/// A grey shield with a tooltip containing the associated message should be
/// presented.
Grey { code: ShieldStateCode, message: String },
/// No shield should be presented.
None,
}

impl From<RustShieldState> for ShieldState {
fn from(value: RustShieldState) -> Self {
match value {
RustShieldState::Red { code, message } => {
Self::Red { code, message: message.to_owned() }
}
RustShieldState::Grey { code, message } => {
Self::Grey { code, message: message.to_owned() }
}
RustShieldState::None => Self::None,
}
}
}

#[derive(uniffi::Object)]
Expand Down
120 changes: 58 additions & 62 deletions crates/matrix-sdk-common/src/deserialized_responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,24 @@ impl VerificationState {
pub fn to_shield_state_strict(&self) -> ShieldState {
match self {
VerificationState::Verified => ShieldState::None,
VerificationState::Unverified(level) => {
let red = ShieldStateColor::Red;
match level {
VerificationLevel::UnverifiedIdentity | VerificationLevel::UnsignedDevice => {
ShieldState::UnverifiedIdentity { color: red }
VerificationState::Unverified(level) => match level {
VerificationLevel::UnverifiedIdentity | VerificationLevel::UnsignedDevice => {
ShieldState::Red {
code: ShieldStateCode::UnverifiedIdentity,
message: UNVERIFIED_IDENTITY,
}
VerificationLevel::None(link) => match link {
DeviceLinkProblem::MissingDevice => {
ShieldState::UnknownDevice { color: red }
}
DeviceLinkProblem::InsecureSource => {
ShieldState::AuthenticityNotGuaranteed { color: red }
}
},
}
}
VerificationLevel::None(link) => match link {
DeviceLinkProblem::MissingDevice => ShieldState::Red {
code: ShieldStateCode::UnknownDevice,
message: UNKNOWN_DEVICE,
},
DeviceLinkProblem::InsecureSource => ShieldState::Red {
code: ShieldStateCode::AuthenticityNotGuaranteed,
message: AUTHENTICITY_NOT_GUARANTEED,
},
},
},
}
}

Expand All @@ -126,19 +128,28 @@ impl VerificationState {
}
VerificationLevel::UnsignedDevice => {
// This is a high warning. The sender hasn't verified his own device.
ShieldState::UnsignedDevice { color: ShieldStateColor::Red }
ShieldState::Red {
code: ShieldStateCode::UnsignedDevice,
message: UNSIGNED_DEVICE,
}
}
VerificationLevel::None(link) => match link {
DeviceLinkProblem::MissingDevice => {
// Have to warn as it could have been a temporary injected device.
// Notice that the device might just not be known at this time, so callers
// should retry when there is a device change for that user.
ShieldState::UnknownDevice { color: ShieldStateColor::Red }
ShieldState::Red {
code: ShieldStateCode::UnknownDevice,
message: UNKNOWN_DEVICE,
}
}
DeviceLinkProblem::InsecureSource => {
// In legacy mode, we tone down this warning as it is quite common and
// mostly noise (due to legacy backup and lack of trusted forwards).
ShieldState::AuthenticityNotGuaranteed { color: ShieldStateColor::Grey }
ShieldState::Grey {
code: ShieldStateCode::AuthenticityNotGuaranteed,
message: AUTHENTICITY_NOT_GUARANTEED,
}
}
},
},
Expand Down Expand Up @@ -170,7 +181,7 @@ pub enum VerificationLevel {
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
pub enum DeviceLinkProblem {
/// The device is missing, either because it was deleted, or you haven't
/// yet downloaded it or the server is erroneously omitting it (federation
/// yet downoaled it or the server is erroneously omitting it (federation
/// lag).
MissingDevice,
/// The key was obtained from an insecure source: imported from a file,
Expand All @@ -181,56 +192,41 @@ pub enum DeviceLinkProblem {
/// Recommended decorations for decrypted messages, representing the message's
/// authenticity properties.
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
pub enum ShieldState {
/// Not enough information available to check the authenticity.
AuthenticityNotGuaranteed { color: ShieldStateColor },
/// The sending device isn't yet known by the Client.
UnknownDevice { color: ShieldStateColor },
/// The sending device hasn't been verified by the sender.
UnsignedDevice { color: ShieldStateColor },
/// The sender hasn't been verified by the Client's user.
UnverifiedIdentity { color: ShieldStateColor },
/// An unencrypted event in an encrypted room.
SentInClear { color: ShieldStateColor },
/// The event is trusted as authentic.
/// A red shield with a tooltip containing the associated message should be
/// presented.
Red {
/// A machine-readable representation.
code: ShieldStateCode,
/// A human readable description.
message: &'static str,
},
/// A grey shield with a tooltip containing the associated message should be
/// presented.
Grey {
/// A machine-readable representation.
code: ShieldStateCode,
/// A human readable description.
message: &'static str,
},
/// No shield should be presented.
None,
}

impl ShieldState {
/// The message (in English) that should be presented.
pub fn message(&self) -> Option<&str> {
match self {
ShieldState::AuthenticityNotGuaranteed { .. } => Some(AUTHENTICITY_NOT_GUARANTEED),
ShieldState::UnknownDevice { .. } => Some(UNKNOWN_DEVICE),
ShieldState::UnsignedDevice { .. } => Some(UNSIGNED_DEVICE),
ShieldState::UnverifiedIdentity { .. } => Some(UNVERIFIED_IDENTITY),
ShieldState::SentInClear { .. } => Some(SENT_IN_CLEAR),
ShieldState::None => None,
}
}

/// A helper method to get the color that should be used.
pub fn color(&self) -> Option<&ShieldStateColor> {
match self {
ShieldState::AuthenticityNotGuaranteed { color } => Some(color),
ShieldState::UnknownDevice { color } => Some(color),
ShieldState::UnsignedDevice { color } => Some(color),
ShieldState::UnverifiedIdentity { color } => Some(color),
ShieldState::SentInClear { color } => Some(color),
ShieldState::None => None,
}
}
}

/// The color of the shield that should be presented to the user.
/// A machine-readable representation of the authenticity for a `ShieldState`.
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))]
pub enum ShieldStateColor {
/// A red shield should be presented.
Red,
/// A grey shield should be presented.
Grey,
pub enum ShieldStateCode {
/// Not enough information available to check the authenticity.
AuthenticityNotGuaranteed,
/// The sending device isn't yet known by the Client.
UnknownDevice,
/// The sending device hasn't been verified by the sender.
UnsignedDevice,
/// The sender hasn't been verified by the Client's user.
UnverifiedIdentity,
/// An unencrypted event in an encrypted room.
SentInClear,
}

/// The algorithm specific information of a decrypted event.
Expand Down
Loading

0 comments on commit 221ace8

Please sign in to comment.