diff --git a/backend/canisters/community/impl/src/jobs/import_groups.rs b/backend/canisters/community/impl/src/jobs/import_groups.rs index 005a658abc..cb1c70ad01 100644 --- a/backend/canisters/community/impl/src/jobs/import_groups.rs +++ b/backend/canisters/community/impl/src/jobs/import_groups.rs @@ -150,7 +150,7 @@ pub(crate) fn finalize_group_import(group_id: ChatId) { chat.events .set_chat(Chat::Channel(state.env.canister_id().into(), channel_id)); - let blocked: Vec<_> = chat.members.blocked.iter().copied().collect(); + let blocked: Vec<_> = chat.members.blocked(); if !blocked.is_empty() { let mut blocked_from_community = Vec::new(); @@ -210,7 +210,7 @@ pub(crate) async fn process_channel_members(group_id: ChatId, channel_id: Channe let (members_to_add_to_community, local_user_index_canister_id) = mutate_state(|state| { let channel = state.data.channels.get(&channel_id).unwrap(); let mut to_add: HashMap = HashMap::new(); - for (user_id, user_type) in channel.chat.members.iter().map(|m| (m.user_id, m.user_type)) { + for (user_id, user_type) in channel.chat.members.iter().map(|m| (m.user_id(), m.user_type())) { if let Some(member) = state.data.members.get_by_user_id_mut(&user_id) { member.channels.insert(channel_id); } else { @@ -333,7 +333,7 @@ pub(crate) fn mark_import_complete(group_id: ChatId, channel_id: ChannelId) { }, group_id, group_name: channel.chat.name.value.clone(), - members: channel.chat.members.iter().map(|m| m.user_id).collect(), + members: channel.chat.members.iter().map(|m| m.user_id()).collect(), other_public_channels: state .data .channels diff --git a/backend/canisters/community/impl/src/lib.rs b/backend/canisters/community/impl/src/lib.rs index 19b2d136ad..32ae0da07e 100644 --- a/backend/canisters/community/impl/src/lib.rs +++ b/backend/canisters/community/impl/src/lib.rs @@ -643,7 +643,7 @@ impl Data { .members .iter() .filter(|m| m.can_member_lapse()) - .map(|m| m.user_id) + .map(|m| m.user_id()) .collect(); } } else { diff --git a/backend/canisters/community/impl/src/model/channels.rs b/backend/canisters/community/impl/src/model/channels.rs index 6aa1129bf4..e9f838e68a 100644 --- a/backend/canisters/community/impl/src/model/channels.rs +++ b/backend/canisters/community/impl/src/model/channels.rs @@ -265,13 +265,13 @@ impl Channel { .and_then(|m| m.display_name().value.clone()); let membership = member.map(|m| GroupMembership { - joined: m.date_added, - role: m.role.value.into(), + joined: m.date_added(), + role: m.role().value.into(), mentions: m.most_recent_mentions(None, &chat.events), notifications_muted: m.notifications_muted.value, my_metrics: chat .events - .user_metrics(&m.user_id, None) + .user_metrics(&m.user_id(), None) .map(|m| m.hydrate()) .unwrap_or_default(), latest_threads: m @@ -285,7 +285,7 @@ impl Channel { .rules_accepted .as_ref() .map_or(false, |version| version.value >= chat.rules.text.version), - lapsed: m.lapsed.value, + lapsed: m.lapsed().value, }); Some(CommunityCanisterChannelSummary { @@ -335,7 +335,7 @@ impl Channel { let member = user_id.and_then(|id| chat.members.get(&id)); if let Some(m) = member { - if m.date_added > since { + if m.date_added() > since { return ChannelUpdates::Added( self.summary(user_id, is_community_member, is_public_community, community_members) .expect("Channel should be accessible"), @@ -354,10 +354,10 @@ impl Channel { .and_then(|m| m.display_name().value.clone()); let membership = member.map(|m| GroupMembershipUpdates { - role: updates.role_changed.then_some(m.role.value.into()), + role: updates.role_changed.then_some(m.role().value.into()), mentions: updates.mentions, notifications_muted: m.notifications_muted.if_set_after(since).cloned(), - my_metrics: self.chat.events.user_metrics(&m.user_id, Some(since)).map(|m| m.hydrate()), + my_metrics: self.chat.events.user_metrics(&m.user_id(), Some(since)).map(|m| m.hydrate()), latest_threads: m .followed_threads .updated_since(since) @@ -370,7 +370,7 @@ impl Channel { .as_ref() .filter(|accepted| updates.rules_changed || accepted.timestamp > since) .map(|accepted| accepted.value >= chat.rules.text.version), - lapsed: m.lapsed.if_set_after(since).copied(), + lapsed: m.lapsed().if_set_after(since).copied(), }); ChannelUpdates::Updated(CommunityCanisterChannelSummaryUpdates { diff --git a/backend/canisters/community/impl/src/queries/c2c_can_issue_access_token_for_channel.rs b/backend/canisters/community/impl/src/queries/c2c_can_issue_access_token_for_channel.rs index 4932c92108..e0f60cd60f 100644 --- a/backend/canisters/community/impl/src/queries/c2c_can_issue_access_token_for_channel.rs +++ b/backend/canisters/community/impl/src/queries/c2c_can_issue_access_token_for_channel.rs @@ -34,7 +34,7 @@ fn can_start_video_call( call_type: VideoCallType, chat: &GroupChatCore, ) -> bool { - if !member.role.is_permitted(chat.permissions.start_video_call) { + if !member.role().is_permitted(chat.permissions.start_video_call) { return false; } diff --git a/backend/canisters/community/impl/src/updates/accept_p2p_swap.rs b/backend/canisters/community/impl/src/updates/accept_p2p_swap.rs index 4a12bfdb3a..13914a784c 100644 --- a/backend/canisters/community/impl/src/updates/accept_p2p_swap.rs +++ b/backend/canisters/community/impl/src/updates/accept_p2p_swap.rs @@ -51,7 +51,7 @@ async fn accept_p2p_swap(args: Args) -> Response { .chat .members .get(&message.sender) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { let community_id = state.env.canister_id().into(); @@ -121,7 +121,7 @@ fn reserve_p2p_swap(args: Args, state: &mut RuntimeState) -> Result return Err(Box::new(UserNotInChannel)), }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return Err(Box::new(UserLapsed)); } diff --git a/backend/canisters/community/impl/src/updates/add_members_to_channel.rs b/backend/canisters/community/impl/src/updates/add_members_to_channel.rs index 343a316112..647c158f87 100644 --- a/backend/canisters/community/impl/src/updates/add_members_to_channel.rs +++ b/backend/canisters/community/impl/src/updates/add_members_to_channel.rs @@ -67,9 +67,9 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result Err(UserLimitReached(limit)) } else if let Some(channel_member) = channel.chat.members.get(&user_id) { let permissions = &channel.chat.permissions; - if !channel_member.role.can_add_members(permissions) { + if !channel_member.role().can_add_members(permissions) { return Err(NotAuthorized); - } else if channel_member.lapsed.value { + } else if channel_member.lapsed().value { return Err(UserLapsed); } diff --git a/backend/canisters/community/impl/src/updates/add_reaction.rs b/backend/canisters/community/impl/src/updates/add_reaction.rs index db69d80d09..50835b1290 100644 --- a/backend/canisters/community/impl/src/updates/add_reaction.rs +++ b/backend/canisters/community/impl/src/updates/add_reaction.rs @@ -48,7 +48,7 @@ fn add_reaction_impl(args: Args, state: &mut RuntimeState) -> Response { args.message_id.into(), ) { if let Some(sender) = channel.chat.members.get(&message.sender) { - if message.sender != user_id && !sender.user_type.is_bot() { + if message.sender != user_id && !sender.user_type().is_bot() { let community_id = state.env.canister_id().into(); state.data.user_event_sync_queue.push( diff --git a/backend/canisters/community/impl/src/updates/c2c_join_channel.rs b/backend/canisters/community/impl/src/updates/c2c_join_channel.rs index 50bb973e34..dbc4d5f7d4 100644 --- a/backend/canisters/community/impl/src/updates/c2c_join_channel.rs +++ b/backend/canisters/community/impl/src/updates/c2c_join_channel.rs @@ -166,10 +166,15 @@ fn is_permitted_to_join( if let Some(channel) = state.data.channels.get(&channel_id) { if let Some(channel_member) = channel.chat.members.get(&member.user_id) { - if !member.lapsed() && !channel_member.lapsed() { + if !member.lapsed() && !channel_member.lapsed().value { return Err(AlreadyInChannel(Box::new( channel - .summary(Some(channel_member.user_id), true, state.data.is_public, &state.data.members) + .summary( + Some(channel_member.user_id()), + true, + state.data.is_public, + &state.data.members, + ) .unwrap(), ))); } @@ -335,7 +340,7 @@ pub(crate) fn join_channel_unchecked( if matches!(result, AddResult::AlreadyInGroup) { let member = channel.chat.members.get(&community_member.user_id).unwrap(); - if member.lapsed() { + if member.lapsed().value { return AddResult::Success(AddMemberSuccess { member: member.clone(), unlapse: true, diff --git a/backend/canisters/community/impl/src/updates/c2c_tip_message.rs b/backend/canisters/community/impl/src/updates/c2c_tip_message.rs index b6360b9662..d3e3fd72b5 100644 --- a/backend/canisters/community/impl/src/updates/c2c_tip_message.rs +++ b/backend/canisters/community/impl/src/updates/c2c_tip_message.rs @@ -52,7 +52,7 @@ fn c2c_tip_message_impl(args: Args, state: &mut RuntimeState) -> Response { args.message_id.into(), ) { if let Some(sender) = channel.chat.members.get(&message.sender) { - if message.sender != user_id && !sender.user_type.is_bot() { + if message.sender != user_id && !sender.user_type().is_bot() { let community_id = state.env.canister_id().into(); state.data.user_event_sync_queue.push( diff --git a/backend/canisters/community/impl/src/updates/delete_channel.rs b/backend/canisters/community/impl/src/updates/delete_channel.rs index a883759aa0..4ef4cf7085 100644 --- a/backend/canisters/community/impl/src/updates/delete_channel.rs +++ b/backend/canisters/community/impl/src/updates/delete_channel.rs @@ -42,9 +42,9 @@ fn delete_channel_impl(channel_id: ChannelId, state: &mut RuntimeState) -> Respo return UserNotInChannel; }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return UserLapsed; - } else if !channel_member.role.can_delete_group() { + } else if !channel_member.role().can_delete_group() { return NotAuthorized; } @@ -76,7 +76,7 @@ fn delete_channel_impl(channel_id: ChannelId, state: &mut RuntimeState) -> Respo now, ); - for user_id in channel.chat.members.iter().map(|m| m.user_id) { + for user_id in channel.chat.members.iter().map(|m| m.user_id()) { state.data.members.mark_member_left_channel(&user_id, channel_id, now); } diff --git a/backend/canisters/community/impl/src/updates/edit_message.rs b/backend/canisters/community/impl/src/updates/edit_message.rs index 8bbce86249..891c75c8c2 100644 --- a/backend/canisters/community/impl/src/updates/edit_message.rs +++ b/backend/canisters/community/impl/src/updates/edit_message.rs @@ -40,7 +40,7 @@ fn edit_message_impl(args: Args, state: &mut RuntimeState) -> Response { return UserNotInChannel; }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return UserLapsed; } diff --git a/backend/canisters/community/impl/src/updates/register_poll_vote.rs b/backend/canisters/community/impl/src/updates/register_poll_vote.rs index e7dc6145bf..2f8181f020 100644 --- a/backend/canisters/community/impl/src/updates/register_poll_vote.rs +++ b/backend/canisters/community/impl/src/updates/register_poll_vote.rs @@ -43,7 +43,7 @@ fn register_poll_vote_impl(args: Args, state: &mut RuntimeState) -> Response { None => return UserNotInChannel, }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return UserLapsed; } @@ -65,7 +65,7 @@ fn register_poll_vote_impl(args: Args, state: &mut RuntimeState) -> Response { match result { RegisterPollVoteResult::Success(votes, creator) => { if creator != user_id { - if channel.chat.members.get(&creator).map_or(false, |m| !m.user_type.is_bot()) { + if channel.chat.members.get(&creator).map_or(false, |m| !m.user_type().is_bot()) { if let Some((message, event_index)) = channel.chat.events.message_internal( EventIndex::default(), args.thread_root_message_index, diff --git a/backend/canisters/community/impl/src/updates/register_proposal_vote.rs b/backend/canisters/community/impl/src/updates/register_proposal_vote.rs index a2a39e796a..0f7463a4d3 100644 --- a/backend/canisters/community/impl/src/updates/register_proposal_vote.rs +++ b/backend/canisters/community/impl/src/updates/register_proposal_vote.rs @@ -77,7 +77,7 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result None => return Err(UserNotInChannel), }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return Err(UserLapsed); } diff --git a/backend/canisters/community/impl/src/updates/register_proposal_vote_v2.rs b/backend/canisters/community/impl/src/updates/register_proposal_vote_v2.rs index 2382a6e3eb..be984821ed 100644 --- a/backend/canisters/community/impl/src/updates/register_proposal_vote_v2.rs +++ b/backend/canisters/community/impl/src/updates/register_proposal_vote_v2.rs @@ -39,7 +39,7 @@ fn register_proposal_vote_impl(args: Args, state: &mut RuntimeState) -> Response None => return UserNotInChannel, }; - if channel_member.lapsed.value { + if channel_member.lapsed().value { return UserLapsed; } diff --git a/backend/canisters/community/impl/src/updates/report_message.rs b/backend/canisters/community/impl/src/updates/report_message.rs index 96feb67fac..59aad0844f 100644 --- a/backend/canisters/community/impl/src/updates/report_message.rs +++ b/backend/canisters/community/impl/src/updates/report_message.rs @@ -64,11 +64,11 @@ fn build_c2c_args(args: &Args, state: &RuntimeState) -> Result<(c2c_report_messa if channel_member.suspended.value { return Err(UserSuspended); - } else if channel_member.lapsed.value { + } else if channel_member.lapsed().value { return Err(UserLapsed); } - if args.delete && !channel_member.role.can_delete_messages(&chat.permissions) { + if args.delete && !channel_member.role().can_delete_messages(&chat.permissions) { return Err(NotAuthorized); } diff --git a/backend/canisters/community/impl/src/updates/send_message.rs b/backend/canisters/community/impl/src/updates/send_message.rs index 17896cef10..f9f33bc8a8 100644 --- a/backend/canisters/community/impl/src/updates/send_message.rs +++ b/backend/canisters/community/impl/src/updates/send_message.rs @@ -284,7 +284,7 @@ fn process_send_message_result( if let Some(channel) = state.data.channels.get(&channel_id) { for user_id in users_mentioned.all_users_mentioned { - if user_id != sender && channel.chat.members.get(&user_id).map_or(false, |m| !m.user_type.is_bot()) { + if user_id != sender && channel.chat.members.get(&user_id).map_or(false, |m| !m.user_type().is_bot()) { activity_events.push((user_id, MessageActivity::Mention)); } } @@ -306,7 +306,7 @@ fn process_send_message_result( .chat .members .get(&message.sender) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { activity_events.push((message.sender, MessageActivity::QuoteReply)); } diff --git a/backend/canisters/group/impl/src/lib.rs b/backend/canisters/group/impl/src/lib.rs index a52451df4c..6cb411007a 100644 --- a/backend/canisters/group/impl/src/lib.rs +++ b/backend/canisters/group/impl/src/lib.rs @@ -132,8 +132,8 @@ impl RuntimeState { .chat .members .iter() - .filter(|m| matches!(m.role.value, GroupRoleInternal::Owner)) - .map(|m| m.user_id) + .filter(|m| matches!(m.role().value, GroupRoleInternal::Owner)) + .map(|m| m.user_id()) .collect(); let owner_count = owners.len() as u128; @@ -174,13 +174,13 @@ impl RuntimeState { let events_ttl = chat.events.get_events_time_to_live(); let membership = GroupMembership { - joined: member.date_added, - role: member.role.value.into(), + joined: member.date_added(), + role: member.role().value.into(), mentions: member.most_recent_mentions(None, &chat.events), notifications_muted: member.notifications_muted.value, my_metrics: chat .events - .user_metrics(&member.user_id, None) + .user_metrics(&member.user_id(), None) .map(|m| m.hydrate()) .unwrap_or_default(), latest_threads: member @@ -194,13 +194,13 @@ impl RuntimeState { .rules_accepted .as_ref() .map_or(false, |version| version.value >= chat.rules.text.version), - lapsed: member.lapsed.value, + lapsed: member.lapsed().value, }; GroupCanisterGroupChatSummary { chat_id: self.env.canister_id().into(), local_user_index_canister_id: self.data.local_user_index_canister_id, - last_updated: chat.last_updated(Some(member.user_id)), + last_updated: chat.last_updated(Some(member.user_id())), name: chat.name.value.clone(), description: chat.description.value.clone(), subtype: chat.subtype.value.clone(), @@ -210,7 +210,7 @@ impl RuntimeState { messages_visible_to_non_members: chat.messages_visible_to_non_members.value, min_visible_event_index, min_visible_message_index, - latest_message: main_events_reader.latest_message_event(Some(member.user_id)), + latest_message: main_events_reader.latest_message_event(Some(member.user_id())), latest_event_index: main_events_reader.latest_event_index().unwrap_or_default(), latest_message_index: main_events_reader.latest_message_index(), joined: membership.joined, @@ -586,7 +586,7 @@ impl Data { } pub fn lookup_user_id(&self, user_id_or_principal: Principal) -> Option { - self.get_member(user_id_or_principal).map(|m| m.user_id) + self.get_member(user_id_or_principal).map(|m| m.user_id()) } pub fn get_member(&self, user_id_or_principal: Principal) -> Option<&GroupMemberInternal> { diff --git a/backend/canisters/group/impl/src/queries/c2c_can_issue_access_token.rs b/backend/canisters/group/impl/src/queries/c2c_can_issue_access_token.rs index 6aefca02ab..61b972e355 100644 --- a/backend/canisters/group/impl/src/queries/c2c_can_issue_access_token.rs +++ b/backend/canisters/group/impl/src/queries/c2c_can_issue_access_token.rs @@ -23,7 +23,7 @@ fn c2c_can_issue_access_token_impl(args: Args, state: &RuntimeState) -> bool { } fn can_start_video_call(member: &GroupMemberInternal, call_type: VideoCallType, chat: &GroupChatCore) -> bool { - if !member.role.is_permitted(chat.permissions.start_video_call) { + if !member.role().is_permitted(chat.permissions.start_video_call) { return false; } diff --git a/backend/canisters/group/impl/src/queries/c2c_name_and_members.rs b/backend/canisters/group/impl/src/queries/c2c_name_and_members.rs index 6e78fb650e..b3db867001 100644 --- a/backend/canisters/group/impl/src/queries/c2c_name_and_members.rs +++ b/backend/canisters/group/impl/src/queries/c2c_name_and_members.rs @@ -10,7 +10,7 @@ fn c2c_name_and_members(_args: Args) -> Response { } fn c2c_name_and_members_impl(state: &RuntimeState) -> Response { - let members = state.data.chat.members.iter().map(|p| p.user_id).collect(); + let members = state.data.chat.members.iter().map(|p| p.user_id()).collect(); Success(SuccessResult { name: state.data.chat.name.value.clone(), diff --git a/backend/canisters/group/impl/src/queries/invite_code.rs b/backend/canisters/group/impl/src/queries/invite_code.rs index 80c53aa078..17904c2766 100644 --- a/backend/canisters/group/impl/src/queries/invite_code.rs +++ b/backend/canisters/group/impl/src/queries/invite_code.rs @@ -11,7 +11,7 @@ fn invite_code(_: Args) -> Response { fn invite_code_impl(state: &RuntimeState) -> Response { let caller = state.env.caller(); if let Some(member) = state.data.get_member(caller) { - if member.role.can_invite_users(&state.data.chat.permissions) { + if member.role().can_invite_users(&state.data.chat.permissions) { return Success(SuccessResult { code: if state.data.invite_code_enabled { state.data.invite_code } else { None }, }); diff --git a/backend/canisters/group/impl/src/queries/summary_updates.rs b/backend/canisters/group/impl/src/queries/summary_updates.rs index a9394c30b2..6a2c97e285 100644 --- a/backend/canisters/group/impl/src/queries/summary_updates.rs +++ b/backend/canisters/group/impl/src/queries/summary_updates.rs @@ -30,23 +30,23 @@ fn summary_updates_impl(updates_since: TimestampMillis, on_behalf_of: Option updates_since) .map(|accepted| accepted.value >= chat.rules.text.version), - lapsed: member.lapsed.if_set_after(updates_since).copied(), + lapsed: member.lapsed().if_set_after(updates_since).copied(), }; Success(SuccessResult { diff --git a/backend/canisters/group/impl/src/updates/accept_p2p_swap.rs b/backend/canisters/group/impl/src/updates/accept_p2p_swap.rs index e14dbfdb5d..1840f73a32 100644 --- a/backend/canisters/group/impl/src/updates/accept_p2p_swap.rs +++ b/backend/canisters/group/impl/src/updates/accept_p2p_swap.rs @@ -51,7 +51,7 @@ async fn accept_p2p_swap(args: Args) -> Response { .chat .members .get(&message.sender) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { state.data.user_event_sync_queue.push( message.sender, @@ -107,11 +107,11 @@ fn reserve_p2p_swap(args: Args, state: &mut RuntimeState) -> Result Response { } let caller = state.env.caller(); - if let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id, m.user_type.is_bot())) { + if let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id(), m.user_type().is_bot())) { let now = state.env.now(); let thread_root_message_index = args.thread_root_message_index; @@ -40,7 +40,7 @@ fn add_reaction_impl(args: Args, state: &mut RuntimeState) -> Response { args.message_id.into(), ) { if let Some(sender) = state.data.chat.members.get(&message.sender) { - if message.sender != user_id && !sender.user_type.is_bot() { + if message.sender != user_id && !sender.user_type().is_bot() { let chat_id = state.env.canister_id().into(); let notifications_muted = state diff --git a/backend/canisters/group/impl/src/updates/c2c_delete_group.rs b/backend/canisters/group/impl/src/updates/c2c_delete_group.rs index 53a71db8cd..5fd737e363 100644 --- a/backend/canisters/group/impl/src/updates/c2c_delete_group.rs +++ b/backend/canisters/group/impl/src/updates/c2c_delete_group.rs @@ -42,14 +42,14 @@ fn prepare(state: &RuntimeState) -> Result { let caller = state.env.caller().into(); if let Some(member) = state.data.chat.members.get(&caller) { - if !member.role.can_delete_group() { + if !member.role().can_delete_group() { Err(NotAuthorized) } else { Ok(PrepareResult { group_index_canister_id: state.data.group_index_canister_id, - deleted_by: member.user_id, + deleted_by: member.user_id(), group_name: state.data.chat.name.value.clone(), - members: state.data.chat.members.iter().map(|m| m.user_id).collect(), + members: state.data.chat.members.iter().map(|m| m.user_id()).collect(), }) } } else { diff --git a/backend/canisters/group/impl/src/updates/c2c_freeze_group.rs b/backend/canisters/group/impl/src/updates/c2c_freeze_group.rs index 2f1baca831..6ccfad8627 100644 --- a/backend/canisters/group/impl/src/updates/c2c_freeze_group.rs +++ b/backend/canisters/group/impl/src/updates/c2c_freeze_group.rs @@ -48,7 +48,7 @@ pub(crate) fn freeze_group_impl( handle_activity_notification(state); if return_members { - SuccessWithMembers(event, state.data.chat.members.iter().map(|p| p.user_id).collect()) + SuccessWithMembers(event, state.data.chat.members.iter().map(|p| p.user_id()).collect()) } else { Success(event) } diff --git a/backend/canisters/group/impl/src/updates/c2c_join_group.rs b/backend/canisters/group/impl/src/updates/c2c_join_group.rs index 74de411286..990017103b 100644 --- a/backend/canisters/group/impl/src/updates/c2c_join_group.rs +++ b/backend/canisters/group/impl/src/updates/c2c_join_group.rs @@ -41,7 +41,7 @@ fn is_permitted_to_join( } if let Some(member) = state.data.chat.members.get(&args.user_id) { - if !member.lapsed.value { + if !member.lapsed().value { let summary = state.summary(member); return Err(AlreadyInGroupV2(Box::new(summary))); } diff --git a/backend/canisters/group/impl/src/updates/c2c_start_import_into_community.rs b/backend/canisters/group/impl/src/updates/c2c_start_import_into_community.rs index c57a7bc9b1..2d415f5a07 100644 --- a/backend/canisters/group/impl/src/updates/c2c_start_import_into_community.rs +++ b/backend/canisters/group/impl/src/updates/c2c_start_import_into_community.rs @@ -17,9 +17,9 @@ fn c2c_start_import_into_community_impl(args: Args, state: &mut RuntimeState) -> if let Some(member) = state.data.chat.members.get(&args.user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; - } else if !member.role.is_owner() { + } else if !member.role().is_owner() { return NotAuthorized; } } else { diff --git a/backend/canisters/group/impl/src/updates/c2c_tip_message.rs b/backend/canisters/group/impl/src/updates/c2c_tip_message.rs index 1fd54e4425..515d8875e4 100644 --- a/backend/canisters/group/impl/src/updates/c2c_tip_message.rs +++ b/backend/canisters/group/impl/src/updates/c2c_tip_message.rs @@ -48,7 +48,7 @@ fn c2c_tip_message_impl(args: Args, state: &mut RuntimeState) -> Response { args.message_id.into(), ) { if let Some(sender) = state.data.chat.members.get(&message.sender) { - if message.sender != user_id && !sender.user_type.is_bot() { + if message.sender != user_id && !sender.user_type().is_bot() { let chat_id = state.env.canister_id().into(); state.push_notification( diff --git a/backend/canisters/group/impl/src/updates/cancel_invites.rs b/backend/canisters/group/impl/src/updates/cancel_invites.rs index 8c6eb3c7fc..5d986c0d16 100644 --- a/backend/canisters/group/impl/src/updates/cancel_invites.rs +++ b/backend/canisters/group/impl/src/updates/cancel_invites.rs @@ -22,12 +22,15 @@ fn cancel_invites_impl(args: Args, state: &mut RuntimeState) -> Response { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } if !matches!( - state.data.chat.cancel_invites(member.user_id, args.user_ids, state.env.now()), + state + .data + .chat + .cancel_invites(member.user_id(), args.user_ids, state.env.now()), CancelInvitesResult::Success ) { return NotAuthorized; diff --git a/backend/canisters/group/impl/src/updates/cancel_p2p_swap.rs b/backend/canisters/group/impl/src/updates/cancel_p2p_swap.rs index b4c0f56ac5..76c23b4557 100644 --- a/backend/canisters/group/impl/src/updates/cancel_p2p_swap.rs +++ b/backend/canisters/group/impl/src/updates/cancel_p2p_swap.rs @@ -31,7 +31,7 @@ fn cancel_p2p_swap_impl(args: Args, state: &mut RuntimeState) -> Result Ok(swap_id), CancelP2PSwapResult::Failure(status) => Err(Box::new(StatusError(status.into()))), diff --git a/backend/canisters/group/impl/src/updates/change_role.rs b/backend/canisters/group/impl/src/updates/change_role.rs index 0ecef4bb00..c03d16a6d9 100644 --- a/backend/canisters/group/impl/src/updates/change_role.rs +++ b/backend/canisters/group/impl/src/updates/change_role.rs @@ -70,10 +70,10 @@ fn prepare(user_id: UserId, state: &RuntimeState) -> Result Result Result { if let Some(member) = state.data.get_member(caller) { if member.suspended.value { Err(UserSuspended) - } else if member.lapsed.value { + } else if member.lapsed().value { return Err(UserLapsed); - } else if !member.role.is_owner() { + } else if !member.role().is_owner() { Err(NotAuthorized) } else { Ok(PrepareResult { caller, - user_id: member.user_id, + user_id: member.user_id(), user_index_canister_id: state.data.user_index_canister_id, group_index_canister_id: state.data.group_index_canister_id, }) diff --git a/backend/canisters/group/impl/src/updates/delete_messages.rs b/backend/canisters/group/impl/src/updates/delete_messages.rs index 3abbcb320e..5d69dd40a2 100644 --- a/backend/canisters/group/impl/src/updates/delete_messages.rs +++ b/backend/canisters/group/impl/src/updates/delete_messages.rs @@ -48,7 +48,7 @@ struct PrepareResult { fn prepare(state: &RuntimeState) -> Result { let caller = state.env.caller(); let (user_id, is_bot) = - if let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id, m.user_type.is_bot())) { + if let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id(), m.user_type().is_bot())) { (user_id, is_bot) } else if caller == state.data.user_index_canister_id { (OPENCHAT_BOT_USER_ID, true) diff --git a/backend/canisters/group/impl/src/updates/disable_invite_code.rs b/backend/canisters/group/impl/src/updates/disable_invite_code.rs index c864f5ab46..ea6c557f8e 100644 --- a/backend/canisters/group/impl/src/updates/disable_invite_code.rs +++ b/backend/canisters/group/impl/src/updates/disable_invite_code.rs @@ -25,8 +25,8 @@ fn disable_invite_code_impl(args: Args, state: &mut RuntimeState) -> Response { return UserSuspended; } - if member.role.can_invite_users(&state.data.chat.permissions) { - let user_id = member.user_id; + if member.role().can_invite_users(&state.data.chat.permissions) { + let user_id = member.user_id(); state.data.invite_code_enabled = false; let now = state.env.now(); diff --git a/backend/canisters/group/impl/src/updates/edit_message.rs b/backend/canisters/group/impl/src/updates/edit_message.rs index 387ae0ffe3..53405d8f0a 100644 --- a/backend/canisters/group/impl/src/updates/edit_message.rs +++ b/backend/canisters/group/impl/src/updates/edit_message.rs @@ -26,8 +26,8 @@ fn edit_message_impl(args: Args, state: &mut RuntimeState) -> Response { } let now = state.env.now(); - let sender = member.user_id; - let is_bot = member.user_type.is_bot(); + let sender = member.user_id(); + let is_bot = member.user_type().is_bot(); let edit_message_args = EditMessageArgs { sender, diff --git a/backend/canisters/group/impl/src/updates/enable_invite_code.rs b/backend/canisters/group/impl/src/updates/enable_invite_code.rs index a3440452ae..5c95221b47 100644 --- a/backend/canisters/group/impl/src/updates/enable_invite_code.rs +++ b/backend/canisters/group/impl/src/updates/enable_invite_code.rs @@ -76,7 +76,7 @@ fn record_event(caller: Principal, change: GroupInviteCodeChange, correlation_id state.data.chat.events.push_main_event( ChatEventInternal::GroupInviteCodeChanged(Box::new(GroupInviteCodeChanged { change, - changed_by: member.user_id, + changed_by: member.user_id(), })), correlation_id, now, @@ -103,7 +103,7 @@ fn prepare(state: &RuntimeState) -> Result { return Err(UserSuspended); } - if member.role.can_invite_users(&state.data.chat.permissions) { + if member.role().can_invite_users(&state.data.chat.permissions) { return Ok(PrepareResult { caller, code: state.data.invite_code, diff --git a/backend/canisters/group/impl/src/updates/follow_thread.rs b/backend/canisters/group/impl/src/updates/follow_thread.rs index b38b5a7fd6..d920034669 100644 --- a/backend/canisters/group/impl/src/updates/follow_thread.rs +++ b/backend/canisters/group/impl/src/updates/follow_thread.rs @@ -20,7 +20,7 @@ fn follow_thread_impl(args: Args, state: &mut RuntimeState) -> Response { let caller = state.env.caller(); - let (user_id, is_bot) = match state.data.get_member(caller).map(|m| (m.user_id, m.user_type.is_bot())) { + let (user_id, is_bot) = match state.data.get_member(caller).map(|m| (m.user_id(), m.user_type().is_bot())) { Some(uid) => uid, None => return UserNotInGroup, }; diff --git a/backend/canisters/group/impl/src/updates/register_poll_vote.rs b/backend/canisters/group/impl/src/updates/register_poll_vote.rs index 255cc513b4..5813ebeb1a 100644 --- a/backend/canisters/group/impl/src/updates/register_poll_vote.rs +++ b/backend/canisters/group/impl/src/updates/register_poll_vote.rs @@ -24,13 +24,13 @@ fn register_poll_vote_impl(args: Args, state: &mut RuntimeState) -> Response { if let Some(member) = state.data.get_member(caller) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } let now = state.env.now(); - let user_id = member.user_id; - let is_bot = member.user_type.is_bot(); + let user_id = member.user_id(); + let is_bot = member.user_type().is_bot(); let min_visible_event_index = member.min_visible_event_index(); let result = state.data.chat.events.register_poll_vote(RegisterPollVoteArgs { @@ -56,7 +56,13 @@ fn register_poll_vote_impl(args: Args, state: &mut RuntimeState) -> Response { args.thread_root_message_index, args.message_index.into(), ) { - if state.data.chat.members.get(&creator).map_or(false, |m| !m.user_type.is_bot()) { + if state + .data + .chat + .members + .get(&creator) + .map_or(false, |m| !m.user_type().is_bot()) + { state.data.user_event_sync_queue.push( creator, GroupCanisterEvent::MessageActivity(MessageActivityEvent { diff --git a/backend/canisters/group/impl/src/updates/register_proposal_vote.rs b/backend/canisters/group/impl/src/updates/register_proposal_vote.rs index f5ffd84f8c..d19f64073e 100644 --- a/backend/canisters/group/impl/src/updates/register_proposal_vote.rs +++ b/backend/canisters/group/impl/src/updates/register_proposal_vote.rs @@ -63,7 +63,7 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result if member.suspended.value { return Err(UserSuspended); - } else if member.lapsed.value { + } else if member.lapsed().value { return Err(UserLapsed); } @@ -77,11 +77,11 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result .message_internal(args.message_index.into()) .and_then(|m| if let MessageContentInternal::GovernanceProposal(p) = m.content { Some(p) } else { None }) { - if let Some(vote) = proposal.votes.get(&member.user_id) { + if let Some(vote) = proposal.votes.get(&member.user_id()) { Err(AlreadyVoted(*vote)) } else { Ok(PrepareResult { - user_id: member.user_id, + user_id: member.user_id(), is_nns: proposal.proposal.is_nns(), governance_canister_id: proposal.governance_canister_id, proposal_id: proposal.proposal.id(), diff --git a/backend/canisters/group/impl/src/updates/register_proposal_vote_v2.rs b/backend/canisters/group/impl/src/updates/register_proposal_vote_v2.rs index 6da9303a10..fc227ec7d8 100644 --- a/backend/canisters/group/impl/src/updates/register_proposal_vote_v2.rs +++ b/backend/canisters/group/impl/src/updates/register_proposal_vote_v2.rs @@ -27,12 +27,12 @@ fn register_proposal_vote_impl(args: Args, state: &mut RuntimeState) -> Response if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } let min_visible_event_index = member.min_visible_event_index(); - let user_id = member.user_id; + let user_id = member.user_id(); match state .data diff --git a/backend/canisters/group/impl/src/updates/remove_participant.rs b/backend/canisters/group/impl/src/updates/remove_participant.rs index c301a5ad45..c5502da776 100644 --- a/backend/canisters/group/impl/src/updates/remove_participant.rs +++ b/backend/canisters/group/impl/src/updates/remove_participant.rs @@ -64,13 +64,13 @@ fn prepare(user_to_remove: UserId, block: bool, state: &RuntimeState) -> Result< if let Some(member) = state.data.get_member(caller) { if member.suspended.value { Err(UserSuspended) - } else if member.lapsed.value { + } else if member.lapsed().value { return Err(UserLapsed); - } else if member.user_id == user_to_remove { + } else if member.user_id() == user_to_remove { Err(CannotRemoveSelf) } else { let user_to_remove_role = match state.data.chat.members.get(&user_to_remove) { - Some(member_to_remove) => member_to_remove.role.value, + Some(member_to_remove) => member_to_remove.role().value, None if block => { if state.data.chat.members.is_blocked(&user_to_remove) { return Err(Success); @@ -82,11 +82,11 @@ fn prepare(user_to_remove: UserId, block: bool, state: &RuntimeState) -> Result< // Check if the caller is authorized to remove the user if member - .role + .role() .can_remove_members_with_role(user_to_remove_role, &state.data.chat.permissions) { Ok(PrepareResult { - removed_by: member.user_id, + removed_by: member.user_id(), local_user_index_canister_id: state.data.local_user_index_canister_id, is_user_to_remove_an_owner: user_to_remove_role.is_owner(), }) diff --git a/backend/canisters/group/impl/src/updates/report_message.rs b/backend/canisters/group/impl/src/updates/report_message.rs index dc76fbc501..bfc134c67f 100644 --- a/backend/canisters/group/impl/src/updates/report_message.rs +++ b/backend/canisters/group/impl/src/updates/report_message.rs @@ -45,15 +45,15 @@ fn build_c2c_args(args: &Args, state: &RuntimeState) -> Result<(c2c_report_messa if member.suspended.value { return Err(UserSuspended); - } else if member.lapsed.value { + } else if member.lapsed().value { return Err(UserLapsed); } - if args.delete && !member.role.can_delete_messages(&chat.permissions) { + if args.delete && !member.role().can_delete_messages(&chat.permissions) { return Err(NotAuthorized); } - let user_id = member.user_id; + let user_id = member.user_id(); if let Some(events_reader) = chat .events diff --git a/backend/canisters/group/impl/src/updates/send_message.rs b/backend/canisters/group/impl/src/updates/send_message.rs index 669f02cd33..543b3d1df2 100644 --- a/backend/canisters/group/impl/src/updates/send_message.rs +++ b/backend/canisters/group/impl/src/updates/send_message.rs @@ -124,8 +124,8 @@ fn validate_caller(state: &RuntimeState) -> Result { Err(UserSuspended) } else { Ok(Caller { - user_id: member.user_id, - user_type: member.user_type, + user_id: member.user_id(), + user_type: member.user_type(), }) } } else if caller == state.data.user_index_canister_id { @@ -162,7 +162,12 @@ fn process_send_message_result( let content = &message_event.event.content; let chat_id = state.env.canister_id().into(); - let sender_is_human = state.data.chat.members.get(&sender).map_or(false, |m| !m.user_type.is_bot()); + let sender_is_human = state + .data + .chat + .members + .get(&sender) + .map_or(false, |m| !m.user_type().is_bot()); let notification = Notification::GroupMessage(GroupMessageNotification { chat_id, @@ -195,7 +200,7 @@ fn process_send_message_result( .chat .members .get(&c.recipient) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { state .data @@ -212,7 +217,7 @@ fn process_send_message_result( .chat .members .get(&user.user_id) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { activity_events.push((user.user_id, MessageActivity::Mention)); } @@ -236,7 +241,7 @@ fn process_send_message_result( .chat .members .get(&message.sender) - .map_or(false, |m| !m.user_type.is_bot()) + .map_or(false, |m| !m.user_type().is_bot()) { activity_events.push((message.sender, MessageActivity::QuoteReply)); } diff --git a/backend/canisters/group/impl/src/updates/set_video_call_presence.rs b/backend/canisters/group/impl/src/updates/set_video_call_presence.rs index 702946beb7..86a0764bac 100644 --- a/backend/canisters/group/impl/src/updates/set_video_call_presence.rs +++ b/backend/canisters/group/impl/src/updates/set_video_call_presence.rs @@ -21,7 +21,7 @@ pub(crate) fn set_video_call_presence_impl(args: Args, state: &mut RuntimeState) let caller = state.env.caller(); - let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id, m.user_type.is_bot())) else { + let Some((user_id, is_bot)) = state.data.get_member(caller).map(|m| (m.user_id(), m.user_type().is_bot())) else { return UserNotInGroup; }; diff --git a/backend/canisters/group/impl/src/updates/toggle_mute_notifications.rs b/backend/canisters/group/impl/src/updates/toggle_mute_notifications.rs index 73cce2c07d..174bf4f7ea 100644 --- a/backend/canisters/group/impl/src/updates/toggle_mute_notifications.rs +++ b/backend/canisters/group/impl/src/updates/toggle_mute_notifications.rs @@ -18,7 +18,7 @@ fn toggle_mute_notifications_impl(args: Args, state: &mut RuntimeState) -> Respo match state.data.get_member_mut(caller) { Some(member) => { member.notifications_muted = Timestamped::new(args.mute, now); - let user_id = member.user_id; + let user_id = member.user_id(); state.data.mark_group_updated_in_user_canister(user_id); Success } diff --git a/backend/canisters/group/impl/src/updates/unblock_user.rs b/backend/canisters/group/impl/src/updates/unblock_user.rs index bf015733c3..878539b27c 100644 --- a/backend/canisters/group/impl/src/updates/unblock_user.rs +++ b/backend/canisters/group/impl/src/updates/unblock_user.rs @@ -26,14 +26,14 @@ fn unblock_user_impl(args: Args, state: &mut RuntimeState) -> Response { } else if let Some(caller_member) = state.data.get_member(caller) { if caller_member.suspended.value { return UserSuspended; - } else if caller_member.lapsed.value { + } else if caller_member.lapsed().value { return UserLapsed; } - let unblocked_by = caller_member.user_id; + let unblocked_by = caller_member.user_id(); if unblocked_by == args.user_id { CannotUnblockSelf - } else if caller_member.role.can_unblock_users(&state.data.chat.permissions) { + } else if caller_member.role().can_unblock_users(&state.data.chat.permissions) { let now = state.env.now(); state.data.chat.members.unblock(args.user_id, now); diff --git a/backend/canisters/group/impl/src/updates/undelete_messages.rs b/backend/canisters/group/impl/src/updates/undelete_messages.rs index 95e1d60f35..2c00750ba0 100644 --- a/backend/canisters/group/impl/src/updates/undelete_messages.rs +++ b/backend/canisters/group/impl/src/updates/undelete_messages.rs @@ -29,7 +29,7 @@ fn undelete_messages_impl(args: Args, state: &mut RuntimeState) -> Response { match state .data .chat - .undelete_messages(member.user_id, args.thread_root_message_index, args.message_ids, now) + .undelete_messages(member.user_id(), args.thread_root_message_index, args.message_ids, now) { UndeleteMessagesResult::Success(messages) => { if !messages.is_empty() { diff --git a/backend/canisters/group/impl/src/updates/update_group_v2.rs b/backend/canisters/group/impl/src/updates/update_group_v2.rs index 4209f88b6b..e247501b34 100644 --- a/backend/canisters/group/impl/src/updates/update_group_v2.rs +++ b/backend/canisters/group/impl/src/updates/update_group_v2.rs @@ -113,7 +113,7 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result let permissions = args.permissions_v2.as_ref(); match state.data.chat.can_update( - &member.user_id, + &member.user_id(), &args.name, &args.description, &args.rules, @@ -125,7 +125,7 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result let avatar_update = args.avatar.as_ref().expand(); Ok(PrepareResult { - my_user_id: member.user_id, + my_user_id: member.user_id(), group_index_canister_id: state.data.group_index_canister_id, is_public: args.public.unwrap_or(state.data.chat.is_public.value), chat_id: state.env.canister_id().into(), @@ -215,7 +215,7 @@ pub fn update_member_expiry(data: &mut Data, prev_gate_config: &Option since).unwrap_or_default(), + role_changed: member.map(|m| m.role().timestamp > since).unwrap_or_default(), mentions, permissions: self.permissions.if_set_after(since).cloned(), updated_events, @@ -497,7 +496,7 @@ impl GroupChatCore { if matches!(message.content, MessageContentInternal::Deleted(_)) { MessageHardDeleted } else if user_id == message.sender - || (deleted_by.deleted_by != message.sender && member.role.can_delete_messages(&self.permissions)) + || (deleted_by.deleted_by != message.sender && member.role().can_delete_messages(&self.permissions)) { Success(Box::new(message.content.hydrate(Some(user_id)))) } else { @@ -523,7 +522,7 @@ impl GroupChatCore { threads .into_iter() .filter_map(|root_message_index| { - self.build_thread_preview(member.user_id, member.min_visible_event_index(), root_message_index) + self.build_thread_preview(member.user_id(), member.min_visible_event_index(), root_message_index) }) .collect(), ) @@ -718,10 +717,10 @@ impl GroupChatCore { // Bump the thread timestamp for all followers member.followed_threads.insert(root_message_index, now); - if member.user_id != sender && !member.user_type.is_bot() && !member.suspended.value { + if member.user_id() != sender && !member.user_type().is_bot() && !member.suspended.value { let mentioned = !mentions_disabled - && (mentions.contains(&member.user_id) - || (is_first_reply && member.user_id == root_message_sender)); + && (mentions.contains(&member.user_id()) + || (is_first_reply && member.user_id() == root_message_sender)); if mentioned { // Mention this member @@ -729,7 +728,7 @@ impl GroupChatCore { } if mentioned || !member.notifications_muted.value { - users_to_notify.insert(member.user_id); + users_to_notify.insert(member.user_id()); } } } @@ -739,16 +738,16 @@ impl GroupChatCore { for member in self .members .iter_mut() - .filter(|m| m.user_id != sender && !m.user_type.is_bot() && !m.suspended.value) + .filter(|m| m.user_id() != sender && !m.user_type().is_bot() && !m.suspended.value) { - let mentioned = !mentions_disabled && (everyone_mentioned || mentions.contains(&member.user_id)); + let mentioned = !mentions_disabled && (everyone_mentioned || mentions.contains(&member.user_id())); if mentioned { // Mention this member member.mentions.add(thread_root_message_index, message_index, message_id, now); } if mentioned || !member.notifications_muted.value { - users_to_notify.insert(member.user_id); + users_to_notify.insert(member.user_id()); } } } @@ -801,7 +800,7 @@ impl GroupChatCore { let permissions = &self.permissions; if !member - .role + .role() .can_send_message(content, thread_root_message_index.is_some(), permissions) { return NotAuthorized; @@ -810,8 +809,8 @@ impl GroupChatCore { Success(PrepareSendMessageSuccess { min_visible_event_index: member.min_visible_event_index(), mentions_disabled: false, - everyone_mentioned: member.role.can_mention_everyone(permissions) && is_everyone_mentioned(content), - sender_user_type: member.user_type, + everyone_mentioned: member.role().can_mention_everyone(permissions) && is_everyone_mentioned(content), + sender_user_type: member.user_type(), }) } @@ -829,10 +828,10 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } - if !member.role.can_react_to_messages(&self.permissions) { + if !member.role().can_react_to_messages(&self.permissions) { return NotAuthorized; } @@ -869,10 +868,10 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } - if !member.role.can_react_to_messages(&self.permissions) { + if !member.role().can_react_to_messages(&self.permissions) { return NotAuthorized; } @@ -903,9 +902,9 @@ impl GroupChatCore { if let Some(member) = self.members.get(&args.user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; - } else if !member.role.can_react_to_messages(&self.permissions) { + } else if !member.role().can_react_to_messages(&self.permissions) { return NotAuthorized; } @@ -932,11 +931,11 @@ impl GroupChatCore { let (is_admin, min_visible_event_index) = if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed() { + } else if member.lapsed().value { return UserLapsed; } ( - member.role.can_delete_messages(&self.permissions), + member.role().can_delete_messages(&self.permissions), member.min_visible_event_index(), ) } else if as_platform_moderator { @@ -999,7 +998,7 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed() { + } else if member.lapsed().value { return UserLapsed; } @@ -1007,7 +1006,7 @@ impl GroupChatCore { let results = self.events.undelete_messages(DeleteUndeleteMessagesArgs { caller: user_id, - is_admin: member.role.can_delete_messages(&self.permissions), + is_admin: member.role().can_delete_messages(&self.permissions), min_visible_event_index, thread_root_message_index, message_ids, @@ -1076,14 +1075,14 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; - } else if !member.role.can_pin_messages(&self.permissions) { + } else if !member.role().can_pin_messages(&self.permissions) { return NotAuthorized; } let min_visible_event_index = member.min_visible_event_index(); - let user_id = member.user_id; + let user_id = member.user_id(); if !self.events.is_accessible(min_visible_event_index, None, message_index.into()) { return MessageNotFound; @@ -1120,9 +1119,9 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; - } else if !member.role.can_pin_messages(&self.permissions) { + } else if !member.role().can_pin_messages(&self.permissions) { return NotAuthorized; } @@ -1133,7 +1132,7 @@ impl GroupChatCore { return MessageNotFound; } - let user_id = member.user_id; + let user_id = member.user_id(); if self.remove_pinned_message(message_index, now) { let push_event_result = self.events.push_main_event( @@ -1198,7 +1197,7 @@ impl GroupChatCore { } // The original caller must be authorized to invite other users - if !member.role.can_invite_users(&self.permissions) { + if !member.role().can_invite_users(&self.permissions) { return NotAuthorized; } @@ -1238,7 +1237,7 @@ impl GroupChatCore { for user_id in invited_users.iter() { self.invited_users.add(UserInvitation { invited: *user_id, - invited_by: member.user_id, + invited_by: member.user_id(), timestamp: now, min_visible_event_index, min_visible_message_index, @@ -1249,7 +1248,7 @@ impl GroupChatCore { self.events.push_main_event( ChatEventInternal::UsersInvited(Box::new(UsersInvited { user_ids: user_ids.clone(), - invited_by: member.user_id, + invited_by: member.user_id(), })), 0, now, @@ -1271,9 +1270,9 @@ impl GroupChatCore { if let Some(member) = self.members.get(&cancelled_by) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; - } else if !member.role.can_invite_users(&self.permissions) { + } else if !member.role().can_invite_users(&self.permissions) { return NotAuthorized; } @@ -1297,7 +1296,7 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { UserSuspended - } else if member.role.is_owner() && self.members.owner_count() == 1 { + } else if member.role().is_owner() && self.members.owner_count() == 1 { LastOwnerCannotLeave } else { Yes @@ -1341,18 +1340,18 @@ impl GroupChatCore { if let Some(member) = self.members.get(&user_id) { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } let target_member_role = match self.members.get(&target_user_id) { - Some(m) => m.role.value, + Some(m) => m.role().value, None if block => GroupRoleInternal::Member, _ => return TargetUserNotInGroup, }; if member - .role + .role() .can_remove_members_with_role(target_member_role, &self.permissions) { // Remove the user from the group @@ -1469,14 +1468,14 @@ impl GroupChatCore { if let Some(member) = self.members.get(user_id) { if member.suspended.value { return Err(UserSuspended); - } else if member.lapsed.value { + } else if member.lapsed().value { return Err(UserLapsed); } let group_permissions = &self.permissions; - if !member.role.can_update_group(group_permissions) - || (permissions.is_some() && !member.role.can_change_permissions()) - || (public.is_some() && !member.role.can_change_group_visibility()) + if !member.role().can_update_group(group_permissions) + || (permissions.is_some() && !member.role().can_change_permissions()) + || (public.is_some() && !member.role().can_change_group_visibility()) { Err(NotAuthorized) } else { @@ -1694,7 +1693,7 @@ impl GroupChatCore { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } @@ -1726,7 +1725,7 @@ impl GroupChatCore { if member.suspended.value { return UserSuspended; - } else if member.lapsed.value { + } else if member.lapsed().value { return UserLapsed; } diff --git a/backend/libraries/group_chat_core/src/members.rs b/backend/libraries/group_chat_core/src/members.rs index 5f4c1b4466..b67b4113a3 100644 --- a/backend/libraries/group_chat_core/src/members.rs +++ b/backend/libraries/group_chat_core/src/members.rs @@ -206,7 +206,7 @@ impl GroupMembers { Some(p) => { if p.suspended.value { return ChangeRoleResult::UserSuspended; - } else if p.lapsed() { + } else if p.lapsed().value { return ChangeRoleResult::UserLapsed; } // Platform moderators can always promote themselves to owner @@ -364,11 +364,11 @@ pub struct ChangeRoleSuccess { #[derive(Serialize, Deserialize, Clone)] pub struct GroupMemberInternal { #[serde(rename = "u")] - pub user_id: UserId, + user_id: UserId, #[serde(rename = "d")] - pub date_added: TimestampMillis, + date_added: TimestampMillis, #[serde(rename = "r", default, skip_serializing_if = "is_default")] - pub role: Timestamped, + role: Timestamped, #[serde(rename = "n")] pub notifications_muted: Timestamped, #[serde(rename = "m", default, skip_serializing_if = "mentions_are_empty")] @@ -384,16 +384,36 @@ pub struct GroupMemberInternal { #[serde(rename = "ra", default, skip_serializing_if = "is_default")] pub rules_accepted: Option>, #[serde(rename = "ut", default, skip_serializing_if = "is_default")] - pub user_type: UserType, + user_type: UserType, #[serde(rename = "me", default, skip_serializing_if = "is_default")] min_visible_event_index: EventIndex, #[serde(rename = "mm", default, skip_serializing_if = "is_default")] min_visible_message_index: MessageIndex, #[serde(rename = "la", default, skip_serializing_if = "is_default")] - pub lapsed: Timestamped, + lapsed: Timestamped, } impl GroupMemberInternal { + pub fn user_id(&self) -> UserId { + self.user_id + } + + pub fn date_added(&self) -> TimestampMillis { + self.date_added + } + + pub fn role(&self) -> &Timestamped { + &self.role + } + + pub fn user_type(&self) -> UserType { + self.user_type + } + + pub fn lapsed(&self) -> &Timestamped { + &self.lapsed + } + pub fn last_updated(&self) -> TimestampMillis { [ self.date_added,