diff --git a/backend/canisters/local_user_index/CHANGELOG.md b/backend/canisters/local_user_index/CHANGELOG.md index 6619d7a603..7fe5acf8e2 100644 --- a/backend/canisters/local_user_index/CHANGELOG.md +++ b/backend/canisters/local_user_index/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [unreleased] +### Added + +- Add `is_oc_controlled_bot` to `GlobalUser` ([#6115](https://github.com/open-chat-labs/open-chat/pull/6115)) + ### Removed - Remove `Invited` gate ([#6112](https://github.com/open-chat-labs/open-chat/pull/6112)) diff --git a/backend/canisters/local_user_index/api/src/lib.rs b/backend/canisters/local_user_index/api/src/lib.rs index 9c810a8bd6..94de3e53b0 100644 --- a/backend/canisters/local_user_index/api/src/lib.rs +++ b/backend/canisters/local_user_index/api/src/lib.rs @@ -72,7 +72,10 @@ pub struct UserRegistered { pub user_id: UserId, pub user_principal: Principal, pub username: String, + #[serde(default)] pub is_bot: bool, + #[serde(default)] + pub is_oc_controlled_bot: bool, pub referred_by: Option, } @@ -161,10 +164,14 @@ pub struct DeleteUser { pub struct GlobalUser { pub user_id: UserId, pub principal: Principal, + #[serde(default)] pub is_bot: bool, + #[serde(default)] pub is_platform_moderator: bool, pub diamond_membership_expires_at: Option, pub unique_person_proof: Option, + #[serde(default)] + pub is_oc_controlled_bot: bool, } #[derive(Serialize, Deserialize, Clone, Debug)] diff --git a/backend/canisters/local_user_index/impl/src/model/global_user_map.rs b/backend/canisters/local_user_index/impl/src/model/global_user_map.rs index dcb69e1776..3ffa502020 100644 --- a/backend/canisters/local_user_index/impl/src/model/global_user_map.rs +++ b/backend/canisters/local_user_index/impl/src/model/global_user_map.rs @@ -11,16 +11,22 @@ pub struct GlobalUserMap { unique_person_proofs: HashMap, platform_moderators: HashSet, bots: HashSet, + #[serde(default)] + oc_controlled_bot_users: HashSet, diamond_membership_expiry_dates: HashMap, } impl GlobalUserMap { - pub fn add(&mut self, principal: Principal, user_id: UserId, is_bot: bool) { + pub fn add(&mut self, principal: Principal, user_id: UserId, is_bot: bool, is_oc_controlled_bot: bool) { self.user_id_to_principal.insert(user_id, principal); self.principal_to_user_id.insert(principal, user_id); if is_bot { self.bots.insert(user_id); + + if is_oc_controlled_bot { + self.oc_controlled_bot_users.insert(user_id); + } } } @@ -95,13 +101,16 @@ impl GlobalUserMap { } fn hydrate_user(&self, user_id: UserId, principal: Principal) -> GlobalUser { + let is_bot = self.bots.contains(&user_id); + GlobalUser { user_id, principal, - is_bot: self.bots.contains(&user_id), + is_bot, is_platform_moderator: self.platform_moderators.contains(&user_id), diamond_membership_expires_at: self.diamond_membership_expiry_dates.get(&user_id).copied(), unique_person_proof: self.unique_person_proofs.get(&user_id).cloned(), + is_oc_controlled_bot: is_bot && self.oc_controlled_bot_users.contains(&user_id), } } } diff --git a/backend/canisters/local_user_index/impl/src/updates/c2c_notify_user_index_events.rs b/backend/canisters/local_user_index/impl/src/updates/c2c_notify_user_index_events.rs index 540badf4c4..81fa1f3a5d 100644 --- a/backend/canisters/local_user_index/impl/src/updates/c2c_notify_user_index_events.rs +++ b/backend/canisters/local_user_index/impl/src/updates/c2c_notify_user_index_events.rs @@ -73,7 +73,10 @@ fn handle_event(event: Event, state: &mut RuntimeState) { ); } Event::UserRegistered(ev) => { - state.data.global_users.add(ev.user_principal, ev.user_id, ev.is_bot); + state + .data + .global_users + .add(ev.user_principal, ev.user_id, ev.is_bot, ev.is_oc_controlled_bot); if let Some(referred_by) = ev.referred_by { if state.data.local_users.get(&referred_by).is_some() { diff --git a/backend/canisters/local_user_index/impl/src/updates/register_user.rs b/backend/canisters/local_user_index/impl/src/updates/register_user.rs index a284d60dc9..d0ad04b789 100644 --- a/backend/canisters/local_user_index/impl/src/updates/register_user.rs +++ b/backend/canisters/local_user_index/impl/src/updates/register_user.rs @@ -191,7 +191,7 @@ fn commit( ) { let now = state.env.now(); state.data.local_users.add(user_id, principal, wasm_version, now); - state.data.global_users.add(principal, user_id, false); + state.data.global_users.add(principal, user_id, false, false); state.push_event_to_user_index(UserIndexEvent::UserRegistered(Box::new(UserRegistered { principal, diff --git a/backend/canisters/user_index/CHANGELOG.md b/backend/canisters/user_index/CHANGELOG.md index e74c90d788..57a993c3d8 100644 --- a/backend/canisters/user_index/CHANGELOG.md +++ b/backend/canisters/user_index/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [unreleased] +### Changed + +- Set `is_oc_controlled_bot` to true when registering the ProposalsBot ([#6115](https://github.com/open-chat-labs/open-chat/pull/6115)) + ## [[2.0.1255](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1255-user_index)] - 2024-07-25 ### Added diff --git a/backend/canisters/user_index/impl/src/lib.rs b/backend/canisters/user_index/impl/src/lib.rs index 9bce3d45cb..5157c30a58 100644 --- a/backend/canisters/user_index/impl/src/lib.rs +++ b/backend/canisters/user_index/impl/src/lib.rs @@ -398,6 +398,7 @@ impl Data { 0, None, true, + true, ); data diff --git a/backend/canisters/user_index/impl/src/model/user.rs b/backend/canisters/user_index/impl/src/model/user.rs index e56731f7ac..b6894bdfa6 100644 --- a/backend/canisters/user_index/impl/src/model/user.rs +++ b/backend/canisters/user_index/impl/src/model/user.rs @@ -40,6 +40,8 @@ pub struct User { pub referred_by: Option, #[serde(rename = "ib", default, skip_serializing_if = "is_default")] pub is_bot: bool, + #[serde(rename = "ocb", default, skip_serializing_if = "is_default")] + pub is_oc_controlled_bot: bool, #[serde(rename = "sd", default, skip_serializing_if = "Option::is_none")] pub suspension_details: Option, #[serde( @@ -102,6 +104,7 @@ impl User { now: TimestampMillis, referred_by: Option, is_bot: bool, + is_oc_controlled_bot: bool, ) -> User { #[allow(deprecated)] User { @@ -119,6 +122,7 @@ impl User { phone_status: PhoneStatus::None, referred_by, is_bot, + is_oc_controlled_bot, suspension_details: None, diamond_membership_details: DiamondMembershipDetailsInternal::default(), moderation_flags_enabled: 0, @@ -242,6 +246,7 @@ impl Default for User { phone_status: PhoneStatus::None, referred_by: None, is_bot: false, + is_oc_controlled_bot: false, suspension_details: None, diamond_membership_details: DiamondMembershipDetailsInternal::default(), moderation_flags_enabled: 0, diff --git a/backend/canisters/user_index/impl/src/model/user_map.rs b/backend/canisters/user_index/impl/src/model/user_map.rs index 40fe61a22b..a927c72e45 100644 --- a/backend/canisters/user_index/impl/src/model/user_map.rs +++ b/backend/canisters/user_index/impl/src/model/user_map.rs @@ -62,11 +62,12 @@ impl UserMap { now: TimestampMillis, referred_by: Option, is_bot: bool, + is_oc_controlled_bot: bool, ) { self.username_to_user_id.insert(&username, user_id); self.principal_to_user_id.insert(principal, user_id); - let user = User::new(principal, user_id, username, now, referred_by, is_bot); + let user = User::new(principal, user_id, username, now, referred_by, is_bot, is_oc_controlled_bot); self.users.insert(user_id, user); if let Some(ref_by) = referred_by { @@ -380,6 +381,7 @@ impl UserMap { user.date_created, None, false, + false, ); self.update(user, date_created, false); } @@ -451,9 +453,9 @@ mod tests { let user_id2: UserId = Principal::from_slice(&[3, 2]).into(); let user_id3: UserId = Principal::from_slice(&[3, 3]).into(); - user_map.register(principal1, user_id1, username1.clone(), 1, None, false); - user_map.register(principal2, user_id2, username2.clone(), 2, None, false); - user_map.register(principal3, user_id3, username3.clone(), 3, None, false); + user_map.register(principal1, user_id1, username1.clone(), 1, None, false, false); + user_map.register(principal2, user_id2, username2.clone(), 2, None, false, false); + user_map.register(principal3, user_id3, username3.clone(), 3, None, false, false); let principal_to_user_id: Vec<_> = user_map .principal_to_user_id @@ -490,7 +492,7 @@ mod tests { let user_id = Principal::from_slice(&[1, 1]).into(); - user_map.register(principal, user_id, username1, 1, None, false); + user_map.register(principal, user_id, username1, 1, None, false, false); if let Some(original) = user_map.get_by_principal(&principal) { let mut updated = original.clone(); diff --git a/backend/canisters/user_index/impl/src/updates/add_local_user_index_canister.rs b/backend/canisters/user_index/impl/src/updates/add_local_user_index_canister.rs index 3b31f57167..45865b66cf 100644 --- a/backend/canisters/user_index/impl/src/updates/add_local_user_index_canister.rs +++ b/backend/canisters/user_index/impl/src/updates/add_local_user_index_canister.rs @@ -69,7 +69,7 @@ fn prepare(args: &Args, state: &RuntimeState) -> Result fn commit(canister_id: CanisterId, wasm_version: BuildVersion, state: &mut RuntimeState) -> Response { if state.data.local_index_map.add_index(canister_id, wasm_version) { - // We need to initialize the new local user index with all of the existing users + // We need to initialize the new local user index with all the existing users for user in state.data.users.iter() { state.data.user_index_event_sync_queue.push( canister_id, @@ -78,6 +78,7 @@ fn commit(canister_id: CanisterId, wasm_version: BuildVersion, state: &mut Runti user_principal: user.principal, username: user.username.clone(), is_bot: user.is_bot, + is_oc_controlled_bot: user.is_oc_controlled_bot, referred_by: user.referred_by, }), ) diff --git a/backend/canisters/user_index/impl/src/updates/c2c_notify_events.rs b/backend/canisters/user_index/impl/src/updates/c2c_notify_events.rs index 423a3d8255..0cd3819891 100644 --- a/backend/canisters/user_index/impl/src/updates/c2c_notify_events.rs +++ b/backend/canisters/user_index/impl/src/updates/c2c_notify_events.rs @@ -130,7 +130,7 @@ fn process_new_user( state .data .users - .register(caller, user_id, username.clone(), now, referred_by, false); + .register(caller, user_id, username.clone(), now, referred_by, false, false); state.data.local_index_map.add_user(local_user_index_canister_id, user_id); @@ -140,6 +140,7 @@ fn process_new_user( user_principal: caller, username: username.clone(), is_bot: false, + is_oc_controlled_bot: false, referred_by, }), Some(local_user_index_canister_id), diff --git a/backend/canisters/user_index/impl/src/updates/c2c_register_bot.rs b/backend/canisters/user_index/impl/src/updates/c2c_register_bot.rs index bcfc2a8561..180d6873f5 100644 --- a/backend/canisters/user_index/impl/src/updates/c2c_register_bot.rs +++ b/backend/canisters/user_index/impl/src/updates/c2c_register_bot.rs @@ -48,7 +48,7 @@ fn c2c_register_bot_impl(args: Args, state: &mut RuntimeState) -> Response { state .data .users - .register(caller, user_id, args.username.clone(), now, None, true); + .register(caller, user_id, args.username.clone(), now, None, true, false); state.push_event_to_all_local_user_indexes( Event::UserRegistered(UserRegistered { @@ -56,6 +56,7 @@ fn c2c_register_bot_impl(args: Args, state: &mut RuntimeState) -> Response { user_principal: caller, username: args.username, is_bot: true, + is_oc_controlled_bot: false, referred_by: None, }), None,