0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-19 19:42:19 +02:00

backup: dist. list w/ privacy ALL has no members

This commit is contained in:
Alex Konradi 2024-08-05 15:46:28 -04:00 committed by GitHub
parent d9187a4db3
commit 3c01c95616
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 26 deletions

View File

@ -43,6 +43,8 @@ pub enum RecipientError {
ContactRegistrationUnknown,
/// distribution list has privacy mode UNKNOWN
DistributionListPrivacyUnknown,
/// distribution list has members but has privacy ALL
DistributionListPrivacyAllWithNonemptyMembers,
/// invalid call link: {0}
InvalidCallLink(#[from] CallLinkError),
/// contact has invalid username
@ -170,9 +172,8 @@ pub enum DistributionListItem<Recipient> {
distribution_id: Uuid,
name: String,
allow_replies: bool,
privacy_mode: PrivacyMode,
#[serde(bound(serialize = "Recipient: serde::Serialize + SerializeOrder"))]
members: UnorderedList<Recipient>,
privacy_mode: PrivacyMode<UnorderedList<Recipient>>,
},
}
@ -185,9 +186,9 @@ pub enum Registration {
#[derive(Debug, serde::Serialize)]
#[cfg_attr(test, derive(PartialEq))]
pub enum PrivacyMode {
OnlyWith,
AllExcept,
pub enum PrivacyMode<RecipientList> {
OnlyWith(RecipientList),
AllExcept(RecipientList),
All,
}
@ -459,9 +460,7 @@ impl<R: Clone, C: LookupPair<RecipientId, DestinationKind, R>>
special_fields: _,
},
) => {
let privacy_mode = PrivacyMode::try_from(privacyMode.enum_value_or_default())?;
let members = memberRecipientIds
let members: UnorderedList<R> = memberRecipientIds
.into_iter()
.map(|id| {
let id = RecipientId(id);
@ -481,12 +480,31 @@ impl<R: Clone, C: LookupPair<RecipientId, DestinationKind, R>>
})
.try_collect()?;
let privacy_mode = match privacyMode.enum_value_or_default() {
proto::distribution_list::PrivacyMode::UNKNOWN => {
return Err(RecipientError::DistributionListPrivacyUnknown)
}
proto::distribution_list::PrivacyMode::ONLY_WITH => {
PrivacyMode::OnlyWith(members)
}
proto::distribution_list::PrivacyMode::ALL_EXCEPT => {
PrivacyMode::AllExcept(members)
}
proto::distribution_list::PrivacyMode::ALL => {
if !members.is_empty() {
return Err(
RecipientError::DistributionListPrivacyAllWithNonemptyMembers,
);
}
PrivacyMode::All
}
};
Self::List {
distribution_id,
name,
allow_replies: allowReplies,
privacy_mode,
members,
}
}
},
@ -494,20 +512,6 @@ impl<R: Clone, C: LookupPair<RecipientId, DestinationKind, R>>
}
}
impl TryFrom<proto::distribution_list::PrivacyMode> for PrivacyMode {
type Error = RecipientError;
fn try_from(value: proto::distribution_list::PrivacyMode) -> Result<Self, Self::Error> {
use proto::distribution_list::PrivacyMode as DistributionPrivacyMode;
match value {
DistributionPrivacyMode::UNKNOWN => Err(RecipientError::DistributionListPrivacyUnknown),
DistributionPrivacyMode::ONLY_WITH => Ok(Self::OnlyWith),
DistributionPrivacyMode::ALL_EXCEPT => Ok(Self::AllExcept),
DistributionPrivacyMode::ALL => Ok(Self::All),
}
}
}
#[cfg(test)]
mod test {
use assert_matches::assert_matches;
@ -814,10 +818,9 @@ mod test {
Destination::<Store>::try_from_with(recipient, &TestContext),
Ok(Destination::DistributionList(DistributionListItem::List {
distribution_id: Uuid::from_bytes(proto::DistributionListItem::TEST_UUID),
privacy_mode: PrivacyMode::AllExcept,
privacy_mode: PrivacyMode::AllExcept(vec![CONTACT_RECIPIENT.clone()].into()),
name: "".to_owned(),
allow_replies: false,
members: vec![CONTACT_RECIPIENT.clone()].into()
}))
);
}
@ -839,6 +842,10 @@ mod test {
.memberRecipientIds
.push(TestContext::SELF_ID.0);
}
fn privacy_mode_all_with_nonempty_members(input: &mut proto::DistributionListItem) {
input.mut_distributionList().privacyMode =
proto::distribution_list::PrivacyMode::ALL.into();
}
#[test_case(invalid_distribution_id, Err(RecipientError::InvalidDistributionId))]
#[test_case(
@ -856,6 +863,10 @@ mod test {
DestinationKind::Self_
))
)]
#[test_case(
privacy_mode_all_with_nonempty_members,
Err(RecipientError::DistributionListPrivacyAllWithNonemptyMembers)
)]
fn destination_distribution_list(
modifier: fn(&mut proto::DistributionListItem),
expected: Result<(), RecipientError>,

View File

@ -502,7 +502,7 @@ mod test {
proto::DistributionList {
name: "list".to_owned(),
memberRecipientIds: recipient_ids,
privacyMode: proto::distribution_list::PrivacyMode::ALL.into(),
privacyMode: proto::distribution_list::PrivacyMode::ONLY_WITH.into(),
..Default::default()
},
)),

View File

@ -47,6 +47,12 @@ impl<T> IntoIterator for UnorderedList<T> {
}
}
impl<T> UnorderedList<T> {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[cfg(test)]
impl<T> From<Vec<T>> for UnorderedList<T> {
fn from(value: Vec<T>) -> Self {