mirror of
https://github.com/signalapp/libsignal.git
synced 2024-09-19 19:42:19 +02:00
Update to latest Backup.proto
- expireTimerVersion must not be 0 when an expirationTimer is set - group members no longer have profile keys
This commit is contained in:
parent
6daa60f395
commit
26bf02e1e3
@ -69,6 +69,8 @@ pub enum ChatError {
|
||||
NoRecipient(RecipientId),
|
||||
/// cannot have a chat with recipient {0:?}, a {1:?}
|
||||
InvalidRecipient(RecipientId, DestinationKind),
|
||||
/// chat with {0:?} has an expirationTimerMs but no expireTimerVersion
|
||||
MissingExpireTimerVersion(RecipientId),
|
||||
/// chat item: {0}
|
||||
ChatItem(#[from] ChatItemError),
|
||||
/// {0:?} already appeared
|
||||
@ -172,6 +174,7 @@ pub struct ChatData<M: Method + ReferencedTypes> {
|
||||
#[serde(bound(serialize = "M::List<ChatItemData<M>>: serde::Serialize"))]
|
||||
pub items: M::List<ChatItemData<M>>,
|
||||
pub expiration_timer: Option<Duration>,
|
||||
pub expiration_timer_version: u32,
|
||||
pub mute_until: Option<Timestamp>,
|
||||
pub style: Option<ChatStyle<M>>,
|
||||
pub pinned_order: Option<PinOrder>,
|
||||
@ -349,6 +352,7 @@ impl<
|
||||
id: _,
|
||||
recipientId,
|
||||
expirationTimerMs,
|
||||
expireTimerVersion,
|
||||
muteUntilMs,
|
||||
pinnedOrder,
|
||||
archived,
|
||||
@ -389,9 +393,15 @@ impl<
|
||||
let mute_until = NonZeroU64::new(muteUntilMs)
|
||||
.map(|t| Timestamp::from_millis(t.get(), "Chat.muteUntilMs"));
|
||||
|
||||
if expiration_timer.is_some() && expireTimerVersion == 0 {
|
||||
return Err(ChatError::MissingExpireTimerVersion(recipient_id));
|
||||
}
|
||||
let expiration_timer_version = expireTimerVersion;
|
||||
|
||||
Ok(Self {
|
||||
recipient,
|
||||
expiration_timer,
|
||||
expiration_timer_version,
|
||||
mute_until,
|
||||
items: Default::default(),
|
||||
style,
|
||||
@ -869,6 +879,7 @@ mod test {
|
||||
recipient: TestContext::test_recipient().clone(),
|
||||
items: Vec::default(),
|
||||
expiration_timer: None,
|
||||
expiration_timer_version: 0,
|
||||
mute_until: None,
|
||||
style: None,
|
||||
pinned_order: None,
|
||||
@ -879,7 +890,12 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
#[test_case(|x| x.expirationTimerMs = 123456 => Ok(()); "with_expiration_timer")]
|
||||
#[test_case(|x| {
|
||||
x.expirationTimerMs = 123456;
|
||||
x.expireTimerVersion = 3;
|
||||
} => Ok(()); "with_expiration_timer")]
|
||||
#[test_case(|x| x.expirationTimerMs = 123456 => Err(ChatError::MissingExpireTimerVersion(TestContext::SELF_ID)); "with_expiration_timer_only")]
|
||||
#[test_case(|x| x.expireTimerVersion = 3 => Ok(()); "with_expire_timer_version_only")]
|
||||
#[test_case(|x| x.muteUntilMs = MillisecondsSinceEpoch::TEST_VALUE.0 => Ok(()); "with mute until")]
|
||||
#[test_case(
|
||||
|x| x.pinnedOrder = TestContext::DUPLICATE_PINNED_ORDER.0.get() =>
|
||||
|
@ -4,7 +4,6 @@
|
||||
//
|
||||
|
||||
use libsignal_core::{Aci, ServiceId, WrongKindOfServiceIdError};
|
||||
use zkgroup::ProfileKeyBytes;
|
||||
|
||||
use super::GroupError;
|
||||
use crate::backup::serialize::{self, SerializeOrder};
|
||||
@ -23,8 +22,6 @@ pub struct GroupMember {
|
||||
#[serde(serialize_with = "serialize::service_id_as_string")]
|
||||
pub user_id: Aci,
|
||||
pub role: Role,
|
||||
#[serde(with = "hex")]
|
||||
pub profile_key: ProfileKeyBytes,
|
||||
pub joined_at_version: u32,
|
||||
pub(super) _limit_construction_to_module: (),
|
||||
}
|
||||
@ -42,7 +39,6 @@ impl TryFrom<proto::group::Member> for GroupMember {
|
||||
let proto::group::Member {
|
||||
userId,
|
||||
role,
|
||||
profileKey,
|
||||
joinedAtVersion,
|
||||
special_fields: _,
|
||||
} = value;
|
||||
@ -61,14 +57,11 @@ impl TryFrom<proto::group::Member> for GroupMember {
|
||||
proto::group::member::Role::DEFAULT => Role::Default,
|
||||
proto::group::member::Role::ADMINISTRATOR => Role::Administrator,
|
||||
};
|
||||
let profile_key = ProfileKeyBytes::try_from(profileKey)
|
||||
.map_err(|_| GroupError::MemberInvalidProfileKey)?;
|
||||
let joined_at_version = joinedAtVersion;
|
||||
|
||||
Ok(GroupMember {
|
||||
user_id,
|
||||
role,
|
||||
profile_key,
|
||||
joined_at_version,
|
||||
_limit_construction_to_module: (),
|
||||
})
|
||||
@ -108,7 +101,6 @@ impl TryFrom<proto::group::MemberPendingProfileKey> for GroupMemberPendingProfil
|
||||
let proto::group::Member {
|
||||
userId,
|
||||
role,
|
||||
profileKey,
|
||||
joinedAtVersion,
|
||||
special_fields: _,
|
||||
} = member
|
||||
@ -125,9 +117,6 @@ impl TryFrom<proto::group::MemberPendingProfileKey> for GroupMemberPendingProfil
|
||||
proto::group::member::Role::DEFAULT => Role::Default,
|
||||
proto::group::member::Role::ADMINISTRATOR => Role::Administrator,
|
||||
};
|
||||
if !profileKey.is_empty() {
|
||||
return Err(GroupError::MemberPendingProfileKeyHasProfileKey);
|
||||
}
|
||||
let joined_at_version = joinedAtVersion;
|
||||
|
||||
let added_by_user_id = ServiceId::parse_from_service_id_binary(&addedByUserId)
|
||||
@ -162,8 +151,6 @@ impl TryFrom<proto::group::MemberPendingProfileKey> for GroupMemberPendingProfil
|
||||
pub struct GroupMemberPendingAdminApproval {
|
||||
#[serde(serialize_with = "serialize::service_id_as_string")]
|
||||
pub user_id: Aci,
|
||||
#[serde(with = "hex")]
|
||||
pub profile_key: ProfileKeyBytes,
|
||||
pub timestamp: Timestamp,
|
||||
pub(super) _limit_construction_to_module: (),
|
||||
}
|
||||
@ -180,7 +167,6 @@ impl TryFrom<proto::group::MemberPendingAdminApproval> for GroupMemberPendingAdm
|
||||
fn try_from(member: proto::group::MemberPendingAdminApproval) -> Result<Self, Self::Error> {
|
||||
let proto::group::MemberPendingAdminApproval {
|
||||
userId,
|
||||
profileKey,
|
||||
timestamp,
|
||||
special_fields: _,
|
||||
} = member;
|
||||
@ -196,13 +182,10 @@ impl TryFrom<proto::group::MemberPendingAdminApproval> for GroupMemberPendingAdm
|
||||
found: e.actual,
|
||||
},
|
||||
)?;
|
||||
let profile_key = ProfileKeyBytes::try_from(profileKey)
|
||||
.map_err(|_| GroupError::MemberInvalidProfileKey)?;
|
||||
let timestamp = Timestamp::from_millis(timestamp, "MemberPendingAdminApproval");
|
||||
|
||||
Ok(GroupMemberPendingAdminApproval {
|
||||
user_id,
|
||||
profile_key,
|
||||
timestamp,
|
||||
_limit_construction_to_module: (),
|
||||
})
|
||||
@ -262,7 +245,6 @@ mod tests {
|
||||
Self {
|
||||
userId: proto::Contact::TEST_ACI.to_vec(),
|
||||
role: proto::group::member::Role::DEFAULT.into(),
|
||||
profileKey: proto::Contact::TEST_PROFILE_KEY.to_vec(),
|
||||
joinedAtVersion: 1,
|
||||
..Default::default()
|
||||
}
|
||||
@ -274,7 +256,6 @@ mod tests {
|
||||
Self {
|
||||
user_id: Aci::from_uuid_bytes(proto::Contact::TEST_ACI),
|
||||
role: Role::Default,
|
||||
profile_key: proto::Contact::TEST_PROFILE_KEY,
|
||||
joined_at_version: 1,
|
||||
_limit_construction_to_module: (),
|
||||
}
|
||||
@ -293,7 +274,6 @@ mod tests {
|
||||
#[test_case(|x| x.userId = vec![] => Err(GroupError::MemberInvalidServiceId { which: "member" }); "empty userId")]
|
||||
#[test_case(|x| x.role = proto::group::member::Role::ADMINISTRATOR.into() => Ok(()); "administrator")]
|
||||
#[test_case(|x| x.role = proto::group::member::Role::UNKNOWN.into() => Err(GroupError::MemberRoleUnknown); "role unknown")]
|
||||
#[test_case(|x| x.profileKey = vec![] => Err(GroupError::MemberInvalidProfileKey); "empty profileKey")]
|
||||
fn member(modifier: impl FnOnce(&mut proto::group::Member)) -> Result<(), GroupError> {
|
||||
let mut member = proto::group::Member::test_data();
|
||||
modifier(&mut member);
|
||||
@ -305,11 +285,7 @@ mod tests {
|
||||
|
||||
pub(crate) fn test_data() -> Self {
|
||||
Self {
|
||||
member: Some(proto::group::Member {
|
||||
profileKey: vec![],
|
||||
..proto::group::Member::test_data()
|
||||
})
|
||||
.into(),
|
||||
member: Some(proto::group::Member::test_data()).into(),
|
||||
timestamp: MillisecondsSinceEpoch::TEST_VALUE.0,
|
||||
addedByUserId: Self::INVITER_ACI.to_vec(),
|
||||
..Default::default()
|
||||
@ -348,7 +324,6 @@ mod tests {
|
||||
#[test_case(|x| x.member.as_mut().unwrap().userId = vec![] => Err(GroupError::MemberInvalidServiceId { which: "invited member" }); "empty userId")]
|
||||
#[test_case(|x| x.member.as_mut().unwrap().role = proto::group::member::Role::ADMINISTRATOR.into() => Ok(()); "administrator")]
|
||||
#[test_case(|x| x.member.as_mut().unwrap().role = proto::group::member::Role::UNKNOWN.into() => Err(GroupError::MemberRoleUnknown); "role unknown")]
|
||||
#[test_case(|x| x.member.as_mut().unwrap().profileKey = proto::Contact::TEST_PROFILE_KEY.to_vec() => Err(GroupError::MemberPendingProfileKeyHasProfileKey); "valid profileKey")]
|
||||
#[test_case(|x| x.addedByUserId = Pni::from_uuid_bytes(proto::Contact::TEST_PNI).service_id_binary() => Err(GroupError::MemberInvalidAci { which: "inviter", found: ServiceIdKind::Pni }); "PNI inviter")]
|
||||
#[test_case(|x| x.addedByUserId = vec![] => Err(GroupError::MemberInvalidServiceId { which: "inviter" }); "empty inviter")]
|
||||
#[test_case(|x| x.addedByUserId = proto::Contact::TEST_ACI.to_vec() => Err(GroupError::MemberPendingProfileKeyWasInvitedBySelf); "self-invite")]
|
||||
@ -364,7 +339,6 @@ mod tests {
|
||||
pub(crate) fn test_data() -> Self {
|
||||
Self {
|
||||
userId: proto::Contact::TEST_ACI.to_vec(),
|
||||
profileKey: proto::Contact::TEST_PROFILE_KEY.to_vec(),
|
||||
timestamp: MillisecondsSinceEpoch::TEST_VALUE.0,
|
||||
..Default::default()
|
||||
}
|
||||
@ -375,7 +349,6 @@ mod tests {
|
||||
pub(crate) fn from_proto_test_data() -> Self {
|
||||
Self {
|
||||
user_id: Aci::from_uuid_bytes(proto::Contact::TEST_ACI),
|
||||
profile_key: proto::Contact::TEST_PROFILE_KEY,
|
||||
timestamp: Timestamp::test_value(),
|
||||
_limit_construction_to_module: (),
|
||||
}
|
||||
@ -395,7 +368,6 @@ mod tests {
|
||||
|
||||
#[test_case(|x| x.userId = Pni::from_uuid_bytes(proto::Contact::TEST_PNI).service_id_binary() => Err(GroupError::MemberInvalidAci { which: "requesting member", found: ServiceIdKind::Pni }); "PNI userId")]
|
||||
#[test_case(|x| x.userId = vec![] => Err(GroupError::MemberInvalidServiceId { which: "requesting member" }); "empty userId")]
|
||||
#[test_case(|x| x.profileKey = vec![] => Err(GroupError::MemberInvalidProfileKey); "empty profileKey")]
|
||||
fn member_pending_admin_approval(
|
||||
modifier: impl FnOnce(&mut proto::group::MemberPendingAdminApproval),
|
||||
) -> Result<(), GroupError> {
|
||||
|
@ -191,8 +191,8 @@ message Group {
|
||||
|
||||
bytes userId = 1;
|
||||
Role role = 2;
|
||||
bytes profileKey = 3;
|
||||
reserved /*presentation*/ 4; // The field is deprecated in the context of static group state
|
||||
reserved /*profileKey*/ 3; // This field is ignored in Backups, in favor of Contact frames for members
|
||||
reserved /*presentation*/ 4; // This field is deprecated in the context of static group state
|
||||
uint32 joinedAtVersion = 5;
|
||||
}
|
||||
|
||||
@ -204,8 +204,8 @@ message Group {
|
||||
|
||||
message MemberPendingAdminApproval {
|
||||
bytes userId = 1;
|
||||
bytes profileKey = 2;
|
||||
reserved /*presentation*/ 3; // The field is deprecated in the context of static group state
|
||||
reserved /*profileKey*/ 2; // This field is ignored in Backups, in favor of Contact frames for members
|
||||
reserved /*presentation*/ 3; // This field is deprecated in the context of static group state
|
||||
uint64 timestamp = 4;
|
||||
}
|
||||
|
||||
@ -243,6 +243,7 @@ message Chat {
|
||||
bool markedUnread = 7;
|
||||
bool dontNotifyForMentionsIfMuted = 8;
|
||||
ChatStyle style = 9;
|
||||
uint32 expireTimerVersion = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1066,7 +1067,7 @@ message StickerPack {
|
||||
message ChatStyle {
|
||||
message Gradient {
|
||||
uint32 angle = 1; // degrees
|
||||
repeated fixed32 colors = 2;
|
||||
repeated fixed32 colors = 2; // 0xAARRGGBB
|
||||
repeated float positions = 3; // percent from 0 to 1
|
||||
}
|
||||
|
||||
@ -1074,7 +1075,7 @@ message ChatStyle {
|
||||
uint64 id = 1;
|
||||
|
||||
oneof color {
|
||||
fixed32 solid = 2;
|
||||
fixed32 solid = 2; // 0xAARRGGBB
|
||||
Gradient gradient = 3;
|
||||
}
|
||||
}
|
||||
@ -1135,6 +1136,8 @@ message ChatStyle {
|
||||
|
||||
oneof wallpaper {
|
||||
WallpaperPreset wallpaperPreset = 1;
|
||||
// This `FilePointer` is expected not to contain a `fileName`, `width`,
|
||||
// `height`, or `caption`.
|
||||
FilePointer wallpaperPhoto = 2;
|
||||
}
|
||||
|
||||
|
@ -113,13 +113,11 @@
|
||||
{
|
||||
"userId": "CujGyCcHTqeyJHQXIn04kA==", // Chewie's ACI
|
||||
"role": "ADMINISTRATOR",
|
||||
"profileKey": "cM4PAiE6xclFBl2wesio4S/tpbDfZHFpYf7BBAsnZI4=",
|
||||
"joinedAtVersion": 0,
|
||||
},
|
||||
{
|
||||
"userId": "X4xWjQEZR72BqruHybcZlQ==", // Han's ACI
|
||||
"role": "ADMINISTRATOR",
|
||||
"profileKey": "YtHHVK+Wo4nPcVpWhC3roMEDu2Tw6kYc9JpLRMq1Q94=",
|
||||
"joinedAtVersion": 0,
|
||||
},
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user