Skip to content

Commit

Permalink
Merge branch 'master' into swaps
Browse files Browse the repository at this point in the history
  • Loading branch information
hpeebles authored Dec 16, 2024
2 parents 655b078 + 1c05c60 commit 078421d
Show file tree
Hide file tree
Showing 105 changed files with 2,000 additions and 1,888 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions backend/canisters/airdrop_bot/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [unreleased]

## [[2.0.1510](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1510-airdrop_bot)] - 2024-12-13

### Changed

- Make `ChannelId` comparisons use their 32bit representation ([#6885](https://github.com/open-chat-labs/open-chat/pull/6885))
Expand Down
11 changes: 11 additions & 0 deletions backend/canisters/community/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [unreleased]

### Changed

- Log error if end video call job fails ([#7066](https://github.com/open-chat-labs/open-chat/pull/7066))
- 2-stage bot messages + bot context in messages ([#7060](https://github.com/open-chat-labs/open-chat/pull/7060))

### Fixed

- Fix `RoleChanged` events which were serialized under the wrong name (part 2) ([#7059](https://github.com/open-chat-labs/open-chat/pull/7059))

## [[2.0.1515](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1515-community)] - 2024-12-13

### Added

- Update community bot config ([#7018](https://github.com/open-chat-labs/open-chat/pull/7018))
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/community/api/can.did
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ type SendMessageResponse = variant {
CommunityFrozen;
RulesNotAccepted;
CommunityRulesNotAccepted;
MessageAlreadyExists;
};

type SendMessageSuccess = record {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub enum Response {
InvalidRequest(String),
CommunityFrozen,
RulesNotAccepted,
MessageAlreadyExists,
CommunityRulesNotAccepted,
UserLapsed,
}
Expand Down
54 changes: 24 additions & 30 deletions backend/canisters/community/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl RuntimeState {
}
}

pub fn caller(&self, bot_id: Option<UserId>) -> CallerResult {
pub fn verified_caller(&self, mut bot_context: Option<BotCaller>) -> CallerResult {
use CallerResult::*;

let caller = self.env.caller();
Expand All @@ -322,37 +322,32 @@ impl RuntimeState {
return Success(Caller::OCBot(OPENCHAT_BOT_USER_ID));
}

if let Some(bot_id) = bot_id {
if let Some(bot) = self.data.bots.get(&bot_id) {
if let Some(member) = self.data.members.get_by_user_id(&bot.added_by) {
if member.suspended().value {
return Suspended;
} else if member.lapsed().value {
return Lapsed;
} else {
return Success(Caller::BotV2(BotCaller {
user_id: bot.added_by,
bot_id,
}));
}
}
}
} else if let Some(member) = self.data.members.get(caller) {
if member.suspended().value {
return Suspended;
} else if member.lapsed().value {
return Lapsed;
let user_or_principal = bot_context.as_ref().map(|bc| bc.initiator.into()).unwrap_or(caller);

let Some(member) = self.data.members.get(user_or_principal) else {
return NotFound;
};

if member.suspended().value {
return Suspended;
} else if member.lapsed().value {
return Lapsed;
}

if let Some(bot_context) = bot_context.take() {
if self.data.bots.get(&bot_context.bot).is_some() {
Success(Caller::BotV2(bot_context))
} else {
return match member.user_type {
UserType::User => Success(Caller::User(member.user_id)),
UserType::BotV2 => NotFound,
UserType::Bot => Success(Caller::Bot(member.user_id)),
UserType::OcControlledBot => Success(Caller::OCBot(member.user_id)),
};
NotFound
}
} else {
match member.user_type {
UserType::User => Success(Caller::User(member.user_id)),
UserType::BotV2 => NotFound,
UserType::Bot => Success(Caller::Bot(member.user_id)),
UserType::OcControlledBot => Success(Caller::OCBot(member.user_id)),
}
}

NotFound
}
}

Expand Down Expand Up @@ -409,7 +404,6 @@ struct Data {
user_cache: UserCache,
user_event_sync_queue: GroupedTimerJobQueue<UserEventBatch>,
stable_memory_keys_to_garbage_collect: Vec<BaseKeyPrefix>,
#[serde(default)]
bots: GroupBots,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ fn post_upgrade(args: Args) {
let (mut data, errors, logs, traces): (Data, Vec<LogEntry>, Vec<LogEntry>, Vec<LogEntry>) =
msgpack::deserialize(reader).unwrap();

canister_logger::init_with_logs(data.test_mode, errors, logs, traces);
data.members.move_member_ids_into_channel_links_map();
data.events.fix_role_changed_events();

canister_logger::init_with_logs(data.test_mode, errors, logs, traces);

let env = init_env(data.rng_seed);
init_state(env, data, args.wasm_version);

Expand Down
31 changes: 26 additions & 5 deletions backend/canisters/community/impl/src/model/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use serde::{Deserialize, Serialize};
use tracing::info;
use types::{
AvatarChanged, BannerChanged, BotAdded, BotRemoved, BotUpdated, ChannelDeleted, ChannelId, ChatId, CommunityMembersRemoved,
CommunityPermissionsChanged, CommunityRoleChanged, CommunityUsersBlocked, CommunityVisibilityChanged, EventIndex,
CommunityPermissionsChanged, CommunityRole, CommunityUsersBlocked, CommunityVisibilityChanged, EventIndex,
EventWrapperInternal, GroupCreated, GroupDescriptionChanged, GroupFrozen, GroupInviteCodeChanged, GroupNameChanged,
GroupRulesChanged, GroupUnfrozen, PrimaryLanguageChanged, TimestampMillis, UserId, UsersInvited, UsersUnblocked,
GroupUnfrozen, PrimaryLanguageChanged, TimestampMillis, UserId, UsersInvited, UsersUnblocked,
};
use user_canister::token_swap_status::CandidType;

mod stable_memory;

Expand Down Expand Up @@ -75,7 +76,7 @@ pub enum CommunityEventInternal {
#[serde(rename = "dc", alias = "DescriptionChanged")]
DescriptionChanged(Box<GroupDescriptionChanged>),
#[serde(rename = "rc", alias = "RulesChanged")]
RulesChanged(Box<GroupRulesChanged>),
RulesChanged(Box<types::GroupRulesChanged>),
#[serde(rename = "ac", alias = "AvatarChanged")]
AvatarChanged(Box<AvatarChanged>),
#[serde(rename = "bc", alias = "BannerChanged")]
Expand All @@ -85,7 +86,7 @@ pub enum CommunityEventInternal {
#[serde(rename = "mr", alias = "MembersRemoved")]
MembersRemoved(Box<CommunityMembersRemoved>),
#[serde(rename = "rl", alias = "RoleChanged")]
RoleChanged(Box<CommunityRoleChanged>),
RoleChanged(Box<types::CommunityRoleChanged>),
#[serde(rename = "ub", alias = "UsersBlocked")]
UsersBlocked(Box<CommunityUsersBlocked>),
#[serde(rename = "uu", alias = "UsersUnblocked")]
Expand Down Expand Up @@ -123,6 +124,21 @@ pub enum RulesChangedOrRoleChanged {
RoleChanged(CommunityRoleChanged),
}

#[derive(CandidType, Serialize, Deserialize, Clone, Debug)]
pub struct GroupRulesChanged {
pub enabled: bool,
pub prev_enabled: bool,
pub changed_by: UserId,
}

#[derive(CandidType, Serialize, Deserialize, Clone, Debug)]
pub struct CommunityRoleChanged {
pub user_ids: Vec<UserId>,
pub changed_by: UserId,
pub old_role: CommunityRole,
pub new_role: CommunityRole,
}

impl CommunityEvents {
pub fn fix_role_changed_events(&mut self) {
let mut count_updated = 0;
Expand All @@ -134,7 +150,12 @@ impl CommunityEvents {
timestamp: event_wrapper.timestamp,
correlation_id: 0,
expires_at: event_wrapper.expires_at,
event: CommunityEventInternal::RoleChanged(Box::new(role)),
event: CommunityEventInternal::RoleChanged(Box::new(types::CommunityRoleChanged {
user_ids: role.user_ids,
changed_by: role.changed_by,
old_role: role.old_role,
new_role: role.new_role,
})),
});
count_updated += 1;
}
Expand Down
45 changes: 2 additions & 43 deletions backend/canisters/community/impl/src/model/members.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ use crate::model::user_groups::{UserGroup, UserGroups};
use candid::Principal;
use constants::calculate_summary_updates_data_removal_cutoff;
use group_community_common::{Member, MemberUpdate, Members};
use principal_to_user_id_map::{deserialize_principal_to_user_id_map_from_heap, PrincipalToUserIdMap};
use principal_to_user_id_map::PrincipalToUserIdMap;
use rand::RngCore;
use serde::de::{SeqAccess, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use serde::{Deserialize, Serialize};
use std::collections::btree_map::Entry::Vacant;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Formatter;
use types::{
is_default, ChannelId, CommunityMember, CommunityPermissions, CommunityRole, PushIfNotContains, TimestampMillis,
Timestamped, UserId, UserType, Version,
Expand All @@ -24,15 +22,11 @@ const MAX_MEMBERS_PER_COMMUNITY: u32 = 100_000;
#[derive(Serialize, Deserialize)]
pub struct CommunityMembers {
members_map: MembersStableStorage,
#[serde(alias = "member_channel_links", deserialize_with = "deserialize_members_and_channels")]
members_and_channels: BTreeMap<UserId, Vec<ChannelId>>,
member_channel_links_removed: BTreeMap<(UserId, ChannelId), TimestampMillis>,
user_groups: UserGroups,
// This includes the userIds of community members and also users invited to the community
#[serde(deserialize_with = "deserialize_principal_to_user_id_map_from_heap")]
principal_to_user_id_map: PrincipalToUserIdMap,
#[deprecated]
member_ids: Vec<UserId>,
owners: BTreeSet<UserId>,
admins: BTreeSet<UserId>,
bots: BTreeMap<UserId, UserType>,
Expand All @@ -46,15 +40,6 @@ pub struct CommunityMembers {
}

impl CommunityMembers {
pub fn move_member_ids_into_channel_links_map(&mut self) {
#[allow(deprecated)]
for user_id in std::mem::take(&mut self.member_ids) {
if let Vacant(e) = self.members_and_channels.entry(user_id) {
e.insert(Vec::new());
}
}
}

pub fn new(
creator_principal: Principal,
creator_user_id: UserId,
Expand Down Expand Up @@ -86,7 +71,6 @@ impl CommunityMembers {
member_channel_links_removed: BTreeMap::new(),
user_groups: UserGroups::default(),
principal_to_user_id_map,
member_ids: Vec::new(),
owners: [creator_user_id].into_iter().collect(),
admins: BTreeSet::new(),
bots: if creator_user_type.is_bot() {
Expand Down Expand Up @@ -839,31 +823,6 @@ impl From<&CommunityMemberInternal> for CommunityMember {
}
}

struct MemberChannelLinksVisitor;

impl<'de> Visitor<'de> for MemberChannelLinksVisitor {
type Value = BTreeMap<UserId, Vec<ChannelId>>;

fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
formatter.write_str("a sequence")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut map: BTreeMap<UserId, Vec<ChannelId>> = BTreeMap::new();
while let Some((user_id, channel_id)) = seq.next_element()? {
map.entry(user_id).or_default().push(channel_id);
}
Ok(map)
}
}

fn deserialize_members_and_channels<'de, D: Deserializer<'de>>(d: D) -> Result<BTreeMap<UserId, Vec<ChannelId>>, D::Error> {
d.deserialize_seq(MemberChannelLinksVisitor)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
5 changes: 4 additions & 1 deletion backend/canisters/community/impl/src/timer_job_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,9 @@ impl Job for MarkP2PSwapExpiredJob {

impl Job for MarkVideoCallEndedJob {
fn execute(self) {
mutate_state(|state| end_video_call_impl(self.0, state));
let response = mutate_state(|state| end_video_call_impl(self.0.clone(), state));
if !matches!(response, community_canister::end_video_call::Response::Success) {
error!(?response, args = ?self.0, "Failed to mark video call ended");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use canister_tracing_macros::trace;
use community_canister::c2c_handle_bot_action::*;
use community_canister::send_message;
use types::bot_actions::MessageContent;
use types::{BotAction, Chat, HandleBotActionsError, MessageContentInitial};
use types::{BotAction, BotCaller, Chat, HandleBotActionsError, MessageContentInitial};
use utils::bots::can_execute_bot_command;

#[update(guard = "caller_is_local_user_index", msgpack = true)]
Expand All @@ -31,8 +31,8 @@ fn c2c_handle_bot_action_impl(args: Args, state: &mut RuntimeState) -> Response
};

match args.action {
BotAction::SendMessage(content) => {
let content = match content {
BotAction::SendMessage(action) => {
let content = match action.content {
MessageContent::Text(text_content) => MessageContentInitial::Text(text_content),
MessageContent::Image(image_content) => MessageContentInitial::Image(image_content),
MessageContent::Video(video_content) => MessageContentInitial::Video(video_content),
Expand All @@ -59,7 +59,12 @@ fn c2c_handle_bot_action_impl(args: Args, state: &mut RuntimeState) -> Response
message_filter_failed: None,
new_achievement: false,
},
Some(args.bot.user_id),
Some(BotCaller {
bot: args.bot.user_id,
initiator: args.initiator,
command_text: args.command_text,
finalised: action.finalised,
}),
state,
) {
send_message::Response::Success(_) => Ok(()),
Expand All @@ -80,10 +85,7 @@ fn is_bot_permitted_to_execute_command(args: &Args, state: &RuntimeState) -> boo
};

// Get the permissions granted to the user in this community/channel
let Some(granted_to_user) = state
.data
.get_user_permissions_for_bot_commands(&args.commanded_by, &channel_id)
else {
let Some(granted_to_user) = state.data.get_user_permissions_for_bot_commands(&args.initiator, &channel_id) else {
return false;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn edit_message_impl(args: Args, state: &mut RuntimeState) -> Response {
message_id: args.message_id,
content: args.content,
block_level_markdown: args.block_level_markdown,
finalise_bot_message: false,
now,
},
Some(&mut state.data.event_store_client),
Expand Down
Loading

0 comments on commit 078421d

Please sign in to comment.