Skip to content

Commit

Permalink
Validation on orders types
Browse files Browse the repository at this point in the history
  • Loading branch information
guillemcordoba committed Jul 8, 2024
1 parent 9a30a19 commit 066a2b1
Show file tree
Hide file tree
Showing 16 changed files with 815 additions and 460 deletions.
565 changes: 276 additions & 289 deletions Cargo.lock

Large diffs are not rendered by default.

62 changes: 62 additions & 0 deletions crates/households_types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,65 @@ pub struct Household {
pub name: String,
pub avatar: EntryHash,
}
#[hdk_entry_helper]
#[derive(Clone, PartialEq)]
pub struct HouseholdMembershipClaim {
pub member_create_link_hash: ActionHash,
pub household_hash: ActionHash,
}

pub const HOUSEHOLD_MEMBERSHIP_CLAIM_ENTRY_TYPE_INDEX: u8 = 1;
pub const HOUSEHOLDS_INTEGRITY_ZOME_NAME: &str = "households_integrity";

pub fn validate_agent_was_member_of_household_at_the_time(
agent_pub_key: AgentPubKey,
chain_top: ActionHash,
household_hash: ActionHash,
) -> ExternResult<ValidateCallbackResult> {
let dna_info = dna_info()?;

let Some(households_zome_index) = dna_info.zome_names.into_iter().position(|z| {
z.to_string()
.eq(&String::from(HOUSEHOLDS_INTEGRITY_ZOME_NAME))
}) else {
return Ok(ValidateCallbackResult::Invalid(format!(
"Unreachable: there is no '{HOUSEHOLDS_INTEGRITY_ZOME_NAME}' integrity zome in this DNA",
)));
};

let agent_activity = must_get_agent_activity(
agent_pub_key,
ChainFilter {
chain_top,
filters: ChainFilters::ToGenesis,
include_cached_entries: true,
},
)?;
let mut deleted_actions: HashSet<ActionHash> = HashSet::new();
for activity in agent_activity.iter() {
if let Action::Delete(delete) = &activity.action.hashed.content {
deleted_actions.insert(delete.deletes_address.clone());
}
}
for activity in agent_activity {
if activity.action.hashed.hash.eq(&household_hash) {
return Ok(ValidateCallbackResult::Valid);
}
if let Some(EntryType::App(app)) = activity.action.hashed.content.entry_type() {
if app.entry_index == HOUSEHOLD_MEMBERSHIP_CLAIM_ENTRY_TYPE_INDEX.into()
&& app.zome_index.0 as usize == households_zome_index
{
let claim_record = must_get_valid_record(activity.action.hashed.hash.clone())?;
let claim = HouseholdMembershipClaim::try_from(claim_record)?;
if claim.household_hash.eq(&household_hash) {
if !deleted_actions.contains(&activity.action.hashed.hash) {
return Ok(ValidateCallbackResult::Valid);
}
}
}
}
}
Ok(ValidateCallbackResult::Invalid(
"Agent was not a member of the household when they committed the given entry".into(),
))
}
52 changes: 9 additions & 43 deletions dnas/plenty/zomes/integrity/households/src/household.rs
Original file line number Diff line number Diff line change
@@ -1,48 +1,6 @@
use hdi::prelude::*;
pub use households_types::*;

use crate::{HouseholdMembershipClaim, UnitEntryTypes};

pub fn was_member_of_household(
agent_pub_key: AgentPubKey,
chain_top: ActionHash,
household_hash: ActionHash,
) -> ExternResult<bool> {
let agent_activity = must_get_agent_activity(
agent_pub_key,
ChainFilter {
chain_top,
filters: ChainFilters::ToGenesis,
include_cached_entries: true,
},
)?;
let mut deleted_actions: HashSet<ActionHash> = HashSet::new();
for activity in agent_activity.iter() {
if let Action::Delete(delete) = &activity.action.hashed.content {
deleted_actions.insert(delete.deletes_address.clone());
}
}
let household_membership_claim_entry_type: AppEntryDef =
UnitEntryTypes::HouseholdMembershipClaim.try_into()?;
for activity in agent_activity {
if activity.action.hashed.hash.eq(&household_hash) {
return Ok(true);
}
if let Some(EntryType::App(app)) = activity.action.hashed.content.entry_type() {
if app.eq(&household_membership_claim_entry_type) {
let claim_record = must_get_valid_record(activity.action.hashed.hash.clone())?;
let claim = HouseholdMembershipClaim::try_from(claim_record)?;
if claim.household_hash.eq(&household_hash) {
if !deleted_actions.contains(&activity.action.hashed.hash) {
return Ok(true);
}
}
}
}
}
Ok(false)
}

pub fn validate_create_household(
_action: EntryCreationAction,
_household: Household,
Expand All @@ -54,7 +12,15 @@ pub fn validate_update_household(
household: Household,
) -> ExternResult<ValidateCallbackResult> {
// TODO: Add adequate validation
// was_member_of_household(action.author, action_hash, household_hash)
// let member_of_household = validate_agent_was_member_of_household_at_the_time(
// action.author,
// action_hash,
// household_hash,
// )?;

// let ValidateCallbackResult::Valid = member_of_household else {
// return Ok(member_of_household);
// };

Ok(ValidateCallbackResult::Valid)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
use crate::LinkTypes;
use hdi::prelude::*;
#[hdk_entry_helper]
#[derive(Clone, PartialEq)]
pub struct HouseholdMembershipClaim {
pub member_create_link_hash: ActionHash,
pub household_hash: ActionHash,
}

pub use households_types::HouseholdMembershipClaim;

pub fn validate_create_household_membership_claim(
action: EntryCreationAction,
Expand Down
63 changes: 31 additions & 32 deletions dnas/plenty/zomes/integrity/households/src/household_to_members.rs
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
use hdi::prelude::*;
use crate::was_member_of_household;
use households_types::validate_agent_was_member_of_household_at_the_time;
pub fn validate_create_link_household_to_members(
action_hash: ActionHash,
action: CreateLink,
base_address: AnyLinkableHash,
_target_address: AnyLinkableHash,
_tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
let household_hash = base_address
.into_action_hash()
.ok_or(
wasm_error!(
WasmErrorInner::Guest(String::from("No action hash associated with link"))
),
)?;
let household_hash =
base_address
.into_action_hash()
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"No action hash associated with link"
))))?;
let record = must_get_valid_record(household_hash.clone())?;
let _household: crate::Household = record
.entry()
.to_app_option()
.map_err(|e| wasm_error!(e))?
.ok_or(
wasm_error!(
WasmErrorInner::Guest(String::from("Linked action must reference an entry"))
),
)?;
if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(
ValidateCallbackResult::Invalid(
String::from("Only members of households can add households members"),
),
);
}
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Linked action must reference an entry"
))))?;
let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};
Ok(ValidateCallbackResult::Valid)
}
pub fn validate_delete_link_household_to_members(
Expand All @@ -43,17 +42,17 @@ pub fn validate_delete_link_household_to_members(
) -> ExternResult<ValidateCallbackResult> {
let household_hash = base
.into_action_hash()
.ok_or(
wasm_error!(
WasmErrorInner::Guest(String::from("No action hash associated with link"))
),
)?;
if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(
ValidateCallbackResult::Invalid(
String::from("Only members of households can remove household members"),
),
);
}
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"No action hash associated with link"
))))?;
let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};
Ok(ValidateCallbackResult::Valid)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use hdi::prelude::*;

use crate::was_member_of_household;
use households_types::validate_agent_was_member_of_household_at_the_time;

pub fn validate_create_link_household_to_requestors(
_action: CreateLink,
Expand Down Expand Up @@ -48,11 +47,15 @@ pub fn validate_delete_link_household_to_requestors(
return Ok(ValidateCallbackResult::Valid);
}

if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(ValidateCallbackResult::Invalid(String::from(
"Only members of households can remove join household requests",
)));
}
let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};
Ok(ValidateCallbackResult::Valid)
}

Expand Down Expand Up @@ -116,10 +119,14 @@ pub fn validate_delete_link_requestor_to_households(
return Ok(ValidateCallbackResult::Valid);
}

if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(ValidateCallbackResult::Invalid(String::from(
"Only members of households can remove join household requests",
)));
}
let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};
Ok(ValidateCallbackResult::Valid)
}
7 changes: 7 additions & 0 deletions dnas/plenty/zomes/integrity/households/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub enum EntryTypes {
Household(Household),
HouseholdMembershipClaim(HouseholdMembershipClaim),
}

#[derive(Serialize, Deserialize)]
#[hdk_link_types]
pub enum LinkTypes {
Expand All @@ -31,6 +32,12 @@ pub enum LinkTypes {
}
#[hdk_extern]
pub fn genesis_self_check(_data: GenesisSelfCheckData) -> ExternResult<ValidateCallbackResult> {
let app_entry_def: AppEntryDef = UnitEntryTypes::HouseholdMembershipClaim.try_into()?;
// See crates/households_types/lib.rs
assert_eq!(
HOUSEHOLD_MEMBERSHIP_CLAIM_ENTRY_TYPE_INDEX,
app_entry_def.entry_index.0
);
Ok(ValidateCallbackResult::Valid)
}
pub fn validate_agent_joining(
Expand Down
27 changes: 20 additions & 7 deletions dnas/plenty/zomes/integrity/households/src/member_to_households.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use hdi::prelude::*;

use crate::was_member_of_household;
use households_types::validate_agent_was_member_of_household_at_the_time;

pub fn validate_create_link_member_to_households(
action_hash: ActionHash,
Expand All @@ -25,9 +25,15 @@ pub fn validate_create_link_member_to_households(
"Linked action must reference an entry"
))))?;

if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(ValidateCallbackResult::Invalid(String::from("")));
}
let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};

Ok(ValidateCallbackResult::Valid)
}
Expand All @@ -46,9 +52,16 @@ pub fn validate_delete_link_member_to_households(
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"No action hash associated with link"
))))?;
if !was_member_of_household(action.author, action_hash, household_hash)? {
return Ok(ValidateCallbackResult::Invalid(String::from("")));
}

let member_of_household = validate_agent_was_member_of_household_at_the_time(
action.author,
action_hash,
household_hash,
)?;

let ValidateCallbackResult::Valid = member_of_household else {
return Ok(member_of_household);
};

Ok(ValidateCallbackResult::Valid)
}
1 change: 1 addition & 0 deletions dnas/plenty/zomes/integrity/orders/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ hdi = { workspace = true }
serde = { workspace = true }
households_types = { path = "../../../../../crates/households_types" }
producers_types = { path = "../../../../../crates/producers_types" }
roles_types = {git = "https://github.com/darksoil-studio/roles", branch = "main" }
Loading

0 comments on commit 066a2b1

Please sign in to comment.