Skip to content

Commit

Permalink
Store unique_human_proof alongside each relevant account (#5993)
Browse files Browse the repository at this point in the history
  • Loading branch information
hpeebles authored Jul 4, 2024
1 parent 866bea4 commit e894d0a
Show file tree
Hide file tree
Showing 28 changed files with 120 additions and 20 deletions.
1 change: 1 addition & 0 deletions backend/canisters/community/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

- Add `LifetimeDiamondMembership` access gate ([#5986](https://github.com/open-chat-labs/open-chat/pull/5986))
- Add `UniquePerson` access gate ([#5993](https://github.com/open-chat-labs/open-chat/pull/5993))

## [[2.0.1194](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1194-community)] - 2024-06-06

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use types::{
ChannelId, CommunityCanisterChannelSummary, CommunityCanisterCommunitySummary, GateCheckFailedReason, TimestampMillis,
UserId, VerifiedCredentialGateArgs,
UniquePersonProof, UserId, VerifiedCredentialGateArgs,
};

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand All @@ -15,6 +15,7 @@ pub struct Args {
pub is_bot: bool,
pub diamond_membership_expires_at: Option<TimestampMillis>,
pub verified_credential_args: Option<VerifiedCredentialGateArgs>,
pub unique_person_proof: Option<UniquePersonProof>,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use types::{CommunityCanisterCommunitySummary, GateCheckFailedReason, TimestampMillis, UserId, VerifiedCredentialGateArgs};
use types::{
CommunityCanisterCommunitySummary, GateCheckFailedReason, TimestampMillis, UniquePersonProof, UserId,
VerifiedCredentialGateArgs,
};

#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct Args {
Expand All @@ -11,6 +14,7 @@ pub struct Args {
pub is_bot: bool,
pub diamond_membership_expires_at: Option<TimestampMillis>,
pub verified_credential_args: Option<VerifiedCredentialGateArgs>,
pub unique_person_proof: Option<UniquePersonProof>,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ async fn add_members_to_channel(args: Args) -> Response {
user_id: *user_id,
diamond_membership_expires_at: diamond_membership_expiry_dates.get(user_id).copied(),
this_canister: prepare_result.this_canister,
unique_person_proof: None,
verified_credential_args: None,
now: prepare_result.now_nanos,
})
Expand Down
18 changes: 16 additions & 2 deletions backend/canisters/community/impl/src/updates/c2c_join_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use gated_groups::{
CheckVerifiedCredentialGateArgs,
};
use group_chat_core::AddResult;
use types::{AccessGate, ChannelId, MemberJoined, TimestampMillis, VerifiedCredentialGateArgs};
use types::{AccessGate, ChannelId, MemberJoined, TimestampMillis, UniquePersonProof, VerifiedCredentialGateArgs};

#[update_msgpack(guard = "caller_is_user_index_or_local_user_index")]
#[trace]
Expand All @@ -32,6 +32,7 @@ async fn c2c_join_channel(args: Args) -> Response {
is_bot: args.is_bot,
diamond_membership_expires_at: args.diamond_membership_expires_at,
verified_credential_args: args.verified_credential_args.clone(),
unique_person_proof: args.unique_person_proof.clone(),
})
.await
{
Expand Down Expand Up @@ -64,8 +65,18 @@ pub(crate) fn join_channel_synchronously(
channel_id: ChannelId,
user_principal: Principal,
diamond_membership_expires_at: Option<TimestampMillis>,
unique_person_proof: Option<UniquePersonProof>,
) {
match read_state(|state| is_permitted_to_join(channel_id, user_principal, diamond_membership_expires_at, None, state)) {
match read_state(|state| {
is_permitted_to_join(
channel_id,
user_principal,
diamond_membership_expires_at,
unique_person_proof,
None,
state,
)
}) {
Ok(None) => {}
Ok(Some(args)) if args.gate.synchronous() => {
if !matches!(check_if_passes_gate_synchronously(args), CheckIfPassesGateResult::Success) {
Expand All @@ -84,6 +95,7 @@ async fn check_gate_then_join_channel(args: &Args) -> Response {
args.channel_id,
args.principal,
args.diamond_membership_expires_at,
args.unique_person_proof.clone(),
args.verified_credential_args.clone(),
state,
)
Expand All @@ -104,6 +116,7 @@ fn is_permitted_to_join(
channel_id: ChannelId,
user_principal: Principal,
diamond_membership_expires_at: Option<TimestampMillis>,
unique_person_proof: Option<UniquePersonProof>,
verified_credential_args: Option<VerifiedCredentialGateArgs>,
state: &RuntimeState,
) -> Result<Option<CheckGateArgs>, Response> {
Expand Down Expand Up @@ -135,6 +148,7 @@ fn is_permitted_to_join(
user_id: member.user_id,
diamond_membership_expires_at,
this_canister: state.env.canister_id(),
unique_person_proof,
verified_credential_args: verified_credential_args.map(|vc| CheckVerifiedCredentialGateArgs {
user_ii_principal: vc.user_ii_principal,
credential_jwt: vc.credential_jwt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ pub(crate) async fn join_community(args: Args) -> Response {
match mutate_state(|state| join_community_impl(&args, state)) {
Ok(public_channel_ids) => {
for c in public_channel_ids {
join_channel_synchronously(c, args.principal, args.diamond_membership_expires_at);
join_channel_synchronously(
c,
args.principal,
args.diamond_membership_expires_at,
args.unique_person_proof.clone(),
);
}
read_state(|state| {
if let Some(member) = state.data.members.get_by_user_id(&args.user_id) {
Expand Down Expand Up @@ -68,6 +73,7 @@ fn is_permitted_to_join(args: &Args, state: &RuntimeState) -> Result<Option<Chec
user_id: args.user_id,
diamond_membership_expires_at: args.diamond_membership_expires_at,
this_canister: state.env.canister_id(),
unique_person_proof: args.unique_person_proof.clone(),
verified_credential_args: args
.verified_credential_args
.as_ref()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ fn c2c_create_proposals_channel(args: Args) -> Response {
is_bot: true,
diamond_membership_expires_at: None,
verified_credential_args: None,
unique_person_proof: None,
},
state,
)
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/group/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

- Add `LifetimeDiamondMembership` access gate ([#5986](https://github.com/open-chat-labs/open-chat/pull/5986))
- Add `UniquePerson` access gate ([#5993](https://github.com/open-chat-labs/open-chat/pull/5993))

## [[2.0.1195](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1195-group)] - 2024-06-06

Expand Down
6 changes: 5 additions & 1 deletion backend/canisters/group/api/src/updates/c2c_join_group.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use types::{GateCheckFailedReason, GroupCanisterGroupChatSummary, TimestampMillis, UserId, VerifiedCredentialGateArgs};
use types::{
GateCheckFailedReason, GroupCanisterGroupChatSummary, TimestampMillis, UniquePersonProof, UserId,
VerifiedCredentialGateArgs,
};

#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct Args {
Expand All @@ -12,6 +15,7 @@ pub struct Args {
pub is_bot: bool,
pub diamond_membership_expires_at: Option<TimestampMillis>,
pub verified_credential_args: Option<VerifiedCredentialGateArgs>,
pub unique_person_proof: Option<UniquePersonProof>,
}

#[derive(CandidType, Serialize, Deserialize, Debug)]
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/group/impl/src/updates/c2c_join_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ fn is_permitted_to_join(args: &Args, state: &RuntimeState) -> Result<Option<Chec
user_id: args.user_id,
diamond_membership_expires_at: args.diamond_membership_expires_at,
this_canister: state.env.canister_id(),
unique_person_proof: args.unique_person_proof.clone(),
verified_credential_args: args
.verified_credential_args
.as_ref()
Expand Down
3 changes: 3 additions & 0 deletions backend/canisters/group_index/impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,8 @@ pub struct AccessGateMetrics {
pub diamond_membership: u32,
#[serde(default)]
pub lifetime_diamond_membership: u32,
#[serde(default)]
pub unique_person: u32,
pub verified_credential: u32,
pub sns_neuron: u32,
pub payment: u32,
Expand All @@ -383,6 +385,7 @@ impl AccessGateMetrics {
match gate {
AccessGate::DiamondMember => self.diamond_membership += 1,
AccessGate::LifetimeDiamondMember => self.lifetime_diamond_membership += 1,
AccessGate::UniquePerson => self.unique_person += 1,
AccessGate::VerifiedCredential(_) => self.verified_credential += 1,
AccessGate::SnsNeuron(_) => self.sns_neuron += 1,
AccessGate::Payment(_) => self.payment += 1,
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/local_user_index/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added

- Add `LifetimeDiamondMembership` access gate ([#5986](https://github.com/open-chat-labs/open-chat/pull/5986))
- Add `UniquePerson` access gate ([#5993](https://github.com/open-chat-labs/open-chat/pull/5993))

### Changed

Expand Down
4 changes: 3 additions & 1 deletion backend/canisters/local_user_index/api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use types::nns::CryptoAmount;
use types::{
CanisterId, ChannelLatestMessageIndex, ChatId, ChitEarnedReason, CommunityId, Cryptocurrency,
DiamondMembershipPlanDuration, MessageContent, MessageContentInitial, MessageId, MessageIndex, PhoneNumber, ReferralType,
SuspensionDuration, TimestampMillis, UpdateUserPrincipalArgs, User, UserId,
SuspensionDuration, TimestampMillis, UniquePersonProof, UpdateUserPrincipalArgs, User, UserId,
};

mod lifecycle;
Expand Down Expand Up @@ -36,6 +36,7 @@ pub enum Event {
UserDeleted(UserDeleted),
SecretKeySet(Vec<u8>),
ChitEarned(ChitEarned),
NotifyUniqueHumanProof(UserId, UniquePersonProof),
}

#[derive(Serialize, Deserialize, Clone, Debug)]
Expand Down Expand Up @@ -162,6 +163,7 @@ pub struct GlobalUser {
pub is_bot: bool,
pub is_platform_moderator: bool,
pub diamond_membership_expires_at: Option<TimestampMillis>,
pub unique_person_proof: Option<UniquePersonProof>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ use candid::Principal;
use local_user_index_canister::GlobalUser;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use types::{TimestampMillis, UserId};
use types::{TimestampMillis, UniquePersonProof, UserId};

#[derive(Serialize, Deserialize, Default)]
pub struct GlobalUserMap {
user_id_to_principal: HashMap<UserId, Principal>,
principal_to_user_id: HashMap<Principal, UserId>,
#[serde(default)]
unique_person_proofs: HashMap<UserId, UniquePersonProof>,
platform_moderators: HashSet<UserId>,
bots: HashSet<UserId>,
diamond_membership_expiry_dates: HashMap<UserId, TimestampMillis>,
Expand Down Expand Up @@ -77,6 +79,10 @@ impl GlobalUserMap {
}
}

pub fn insert_unique_person_proof(&mut self, user_id: UserId, proof: UniquePersonProof) {
self.unique_person_proofs.insert(user_id, proof);
}

pub fn is_bot(&self, user_id: &UserId) -> bool {
self.bots.contains(user_id)
}
Expand All @@ -96,6 +102,7 @@ impl GlobalUserMap {
is_bot: self.bots.contains(&user_id),
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(),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,5 +193,8 @@ fn handle_event(event: Event, state: &mut RuntimeState) {
})),
);
}
Event::NotifyUniqueHumanProof(user_id, proof) => {
state.data.global_users.insert_unique_person_proof(user_id, proof);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ async fn join_channel(args: Args) -> Response {
is_bot: user_details.is_bot,
diamond_membership_expires_at: user_details.diamond_membership_expires_at,
verified_credential_args: args.verified_credential_args.clone(),
unique_person_proof: user_details.unique_person_proof.clone(),
};
match community_canister_c2c_client::c2c_join_channel(args.community_id.into(), &c2c_args).await {
Ok(response) => match response {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async fn join_community(args: Args) -> Response {
is_bot: user_details.is_bot,
diamond_membership_expires_at: user_details.diamond_membership_expires_at,
verified_credential_args: args.verified_credential_args,
unique_person_proof: user_details.unique_person_proof.clone(),
};
match community_canister_c2c_client::c2c_join_community(args.community_id.into(), &c2c_args).await {
Ok(response) => match response {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ async fn join_group(args: Args) -> Response {
is_bot: user_details.is_bot,
diamond_membership_expires_at: user_details.diamond_membership_expires_at,
verified_credential_args: args.verified_credential_args.clone(),
unique_person_proof: user_details.unique_person_proof.clone(),
};
match group_canister_c2c_client::c2c_join_group(args.chat_id.into(), &c2c_args).await {
Ok(response) => match response {
Expand Down
4 changes: 4 additions & 0 deletions backend/canisters/user_index/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [unreleased]

### Added

- Store `unique_person_proof` alongside each relevant account ([#5993](https://github.com/open-chat-labs/open-chat/pull/5993))

## [[2.0.1225](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1225-user_index)] - 2024-07-04

### Changed
Expand Down
13 changes: 9 additions & 4 deletions backend/canisters/user_index/impl/src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
use types::{
is_default, is_empty_slice, CyclesTopUp, CyclesTopUpInternal, PhoneNumber, RegistrationFee, SuspensionAction,
SuspensionDuration, TimestampMillis, UserId, UserSummary, UserSummaryStable, UserSummaryV2, UserSummaryVolatile,
SuspensionDuration, TimestampMillis, UniquePersonProof, UserId, UserSummary, UserSummaryStable, UserSummaryV2,
UserSummaryVolatile,
};

#[derive(Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -58,7 +59,9 @@ pub struct User {
#[serde(rename = "cu", default)]
pub chit_updated: TimestampMillis,
#[serde(rename = "lc", default)]
pub lastest_chit_event: TimestampMillis,
pub latest_chit_event: TimestampMillis,
#[serde(rename = "uh", default, skip_serializing_if = "Option::is_none")]
pub unique_person_proof: Option<UniquePersonProof>,
}

impl User {
Expand Down Expand Up @@ -112,7 +115,8 @@ impl User {
chit_updated: now,
streak: 0,
streak_ends: 0,
lastest_chit_event: 0,
latest_chit_event: 0,
unique_person_proof: None,
}
}

Expand Down Expand Up @@ -223,7 +227,8 @@ impl Default for User {
streak: 0,
streak_ends: 0,
chit_updated: 0,
lastest_chit_event: 0,
latest_chit_event: 0,
unique_person_proof: None,
}
}
}
4 changes: 2 additions & 2 deletions backend/canisters/user_index/impl/src/model/user_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ impl UserMap {
return false;
};

if chit_event_timestamp <= user.lastest_chit_event {
if chit_event_timestamp <= user.latest_chit_event {
return false;
}

user.lastest_chit_event = chit_event_timestamp;
user.latest_chit_event = chit_event_timestamp;
user.chit_balance = chit_balance;
user.streak = streak;
user.streak_ends = streak_ends;
Expand Down
1 change: 1 addition & 0 deletions backend/canisters/user_index/impl/src/timer_job_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ impl Job for JoinUserToGroup {
.get_by_user_id(&self.user_id)
.and_then(|u| u.diamond_membership_details.expires_at()),
verified_credential_args: None,
unique_person_proof: None,
})
}) {
ic_cdk::spawn(join_group(self.group_id, args, self.attempt));
Expand Down
2 changes: 1 addition & 1 deletion backend/integration_tests/src/client/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ generate_query_call!(updates);
generate_update_call!(accept_p2p_swap);
generate_update_call!(add_reaction);
generate_update_call!(block_user);
generate_update_call!(claim_daily_chit);
generate_update_call!(cancel_message_reminder);
generate_update_call!(cancel_p2p_swap);
generate_update_call!(claim_daily_chit);
generate_update_call!(create_community);
generate_update_call!(create_group);
generate_update_call!(delete_community);
Expand Down
Loading

0 comments on commit e894d0a

Please sign in to comment.