From 820cd5abc4233d0ca53726cc59675276b8f76b94 Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:44:13 +0200 Subject: [PATCH 1/6] Update anchor.rs in Section Add validation --- .../zomes/courses/code/src/section/anchor.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/dna/course/zomes/courses/code/src/section/anchor.rs b/dna/course/zomes/courses/code/src/section/anchor.rs index 4dac6b6..cb8d697 100644 --- a/dna/course/zomes/courses/code/src/section/anchor.rs +++ b/dna/course/zomes/courses/code/src/section/anchor.rs @@ -48,17 +48,14 @@ pub fn section_anchor_def() -> ValidatingEntryType { }, validation: | validation_data: hdk::EntryValidationData| { match validation_data{ - EntryValidationData::Create { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Create { entry, validation_data } => { + validation::anchor_create(entry, validation_data) }, EntryValidationData::Modify { .. } => { - // TODO: implement validation - Ok(()) + validation::anchor_modify() }, - EntryValidationData::Delete { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Delete { old_entry, old_entry_header, validation_data } => { + validation::anchor_delete(old_entry, old_entry_header, validation_data) } } }, @@ -69,8 +66,8 @@ pub fn section_anchor_def() -> ValidatingEntryType { validation_package:||{ hdk::ValidationPackageDefinition::Entry }, - validation:|_validation_data: hdk::LinkValidationData|{ - Ok(()) + validation:|validation_data: hdk::LinkValidationData|{ + validation::anchor_to_section_link(validation_data) } ), to!( From 355c07bd1ed754e2933c928752c250b2bd2b34a4 Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:45:16 +0200 Subject: [PATCH 2/6] Update entry.rs in Section Add validation --- .../zomes/courses/code/src/section/entry.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dna/course/zomes/courses/code/src/section/entry.rs b/dna/course/zomes/courses/code/src/section/entry.rs index ebed85b..d5591dc 100644 --- a/dna/course/zomes/courses/code/src/section/entry.rs +++ b/dna/course/zomes/courses/code/src/section/entry.rs @@ -5,6 +5,9 @@ use hdk::{ holochain_persistence_api::cas::content::Address, }; use holochain_entry_utils::HolochainEntry; +use super::validation; + +pub const MAX_TITLE_LEN: usize = 50; #[derive(Serialize, Deserialize, Debug, DefaultJson, Clone)] pub struct Section { @@ -46,17 +49,14 @@ pub fn entry_def() -> ValidatingEntryType { }, validation: | validation_data: hdk::EntryValidationData
| { match validation_data { - EntryValidationData::Create { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Create { entry, validation_data } => { + validation::create(entry, validation_data) }, - EntryValidationData::Modify { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Modify { new_entry, old_entry, old_entry_header, validation_data } => { + validation::modify(new_entry, old_entry, old_entry_header, validation_data) }, - EntryValidationData::Delete { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Delete { old_entry, old_entry_header, validation_data } => { + validation::delete(old_entry, old_entry_header, validation_data) } } }, From c16eaf0cbde23e09c09bacf2b08b1972654f8ce7 Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:46:16 +0200 Subject: [PATCH 3/6] Create validation.rs in Section --- .../courses/code/src/section/validation.rs | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 dna/course/zomes/courses/code/src/section/validation.rs diff --git a/dna/course/zomes/courses/code/src/section/validation.rs b/dna/course/zomes/courses/code/src/section/validation.rs new file mode 100644 index 0000000..b0d72ec --- /dev/null +++ b/dna/course/zomes/courses/code/src/section/validation.rs @@ -0,0 +1,68 @@ +use crate::helper::validate_entity_title; + +pub fn create(entry: Section, validation_data: ValidationData) -> Result<(), String> { + validate_entity_title(entry.title, entity_name: &Section::entry_type(), allowed_length: MAX_TITLE_LEN); +} + +pub fn modify( + new_entry: Section, + old_entry: Section, + _old_entry_header: ChainHeader, + validation_data: ValidationData, +) -> Result<(), String> { + helper::validate_only_teacher_can_do( + &old_entry.teacher_address, + validation_data.sources(), + "modify the section", + )?; + helper::validate_entity_title(&new_entry.title, &Section::entry_type(), MAX_TITLE_LEN)?; + validate_no_teacher_change(old_entry, new_entry) +} + +// this fn is only needed in the current module so it's private +fn validate_no_teacher_change(old_entry: Section, new_entry: Section) -> Result<(), String> { + if new_entry.teacher_address != old_entry.teacher_address { + return Err(String::from("Cannot change the teacher of the section")); + } + Ok(()) +} + +pub fn delete( + entry: Section, + _entry_header: ChainHeader, + validation_data: ValidationData, +) -> Result<(), String> { + helper::validate_only_teacher_can_do( + &entry.teacher_address, + validation_data.sources(), + "delete the section", + ) +} + +pub fn anchor_to_section_link(validation_data: LinkValidationData) -> Result<(), String> { + match validation_data { + hdk::LinkValidationData::LinkAdd { + link, + validation_data, + } => { + // get author of this entry + let author: HashString = validation_data.package.chain_header.provenances()[0].source(); + // get link base: entry from which the link goes + let base: SectionAnchor = hdk::utils::get_as_type(link.link.base().clone())?; + // get link target: entry to which the link goes + let target: Section = hdk::utils::get_as_type(link.link.target().clone())?; + if base.teacher_address != target.teacher_address { + // notice that we're using return and ending this statement with ; symbol + // You can do both: skip ; symbol in the last fn statement or explicitly add return to it and then leave ; as is + return Err(String::from( + "Can't link SectionAnchor to Section because their teacher addresses are different", + )); + } else if author != base.teacher_address { + return Err(String::from( + "Can't link SectionAnchor to Section because your address isn't specified as teacher_address for this course" + )); + } + Ok(()) + } + } +} From 98dfc9b5c6ca872884e3fe311b709c46f126276f Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:47:22 +0200 Subject: [PATCH 4/6] Add mod validation to mod.rs in Content --- dna/course/zomes/courses/code/src/content/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/dna/course/zomes/courses/code/src/content/mod.rs b/dna/course/zomes/courses/code/src/content/mod.rs index d002a89..b68caaa 100644 --- a/dna/course/zomes/courses/code/src/content/mod.rs +++ b/dna/course/zomes/courses/code/src/content/mod.rs @@ -1,2 +1,3 @@ pub mod entry; pub mod handlers; +pub mod validation; From 2b48fe8c4751788e1abba96fe7709f9d92426e46 Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:48:17 +0200 Subject: [PATCH 5/6] Update entry.rs in Content Add validation --- .../zomes/courses/code/src/content/entry.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dna/course/zomes/courses/code/src/content/entry.rs b/dna/course/zomes/courses/code/src/content/entry.rs index 41a6e02..96caee9 100644 --- a/dna/course/zomes/courses/code/src/content/entry.rs +++ b/dna/course/zomes/courses/code/src/content/entry.rs @@ -1,5 +1,8 @@ use hdk::prelude::*; use holochain_entry_utils::HolochainEntry; +use super::validation; + +pub const MAX_NAME_LEN: usize = 50; // NOTE: using self::DefaultJson to disambiguate usage of DefaultJson from this module (hdk::prelude imports it) #[derive(Serialize, Deserialize, Debug, self::DefaultJson, Clone)] @@ -45,17 +48,14 @@ pub fn section_entry_def() -> ValidatingEntryType { }, validation: | validation_data: hdk::EntryValidationData| { match validation_data { - EntryValidationData::Create { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Create { entry, validation_data } => { + validation::create(entry, validation_data) }, - EntryValidationData::Modify { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Modify { new_entry, old_entry, old_entry_header, validation_data } => { + validation::modify(new_entry, old_entry, old_entry_header, validation_data) }, - EntryValidationData::Delete { .. } => { - // TODO: implement validation - Ok(()) + EntryValidationData::Delete { old_entry, old_entry_header, validation_data } => { + validation::delete(old_entry, old_entry_header, validation_data) } } } From 813018455f3ea895cab5d635f611c38b60fe10dd Mon Sep 17 00:00:00 2001 From: falyhery <32633685+falyhery@users.noreply.github.com> Date: Tue, 18 Aug 2020 17:49:09 +0200 Subject: [PATCH 6/6] Create validation.rs in Content --- .../courses/code/src/content/validation.rs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 dna/course/zomes/courses/code/src/content/validation.rs diff --git a/dna/course/zomes/courses/code/src/content/validation.rs b/dna/course/zomes/courses/code/src/content/validation.rs new file mode 100644 index 0000000..56d36b7 --- /dev/null +++ b/dna/course/zomes/courses/code/src/content/validation.rs @@ -0,0 +1,80 @@ +use crate::helper::validate_entity_title; + +pub fn create(entry: Content, validation_data: ValidationData) -> Result<(), String> { + validate_entity_title(entry.name, entity_name: "Content", allowed_length: MAX_NAME_LEN) +} + +pub fn modify( + new_entry: Content, + old_entry: Content, + _old_entry_header: ChainHeader, + validation_data: ValidationData, +) -> Result<(), String> { + helper::validate_only_teacher_can_do( + &old_entry.teacher_address, + validation_data.sources(), + "modify the content", + )?; + helper::validate_entity_title(&new_entry.name, &Content::entry_type(), MAX_NAME_LEN)?; + validate_no_teacher_change(old_entry, new_entry) +} + +fn validate_no_teacher_change(old_entry: Content, new_entry: Content) -> Result<(), String> { + if new_entry.teacher_address != old_entry.teacher_address { + return Err(String::from("Cannot change the teacher of the content")); + } + Ok(()) +} + +pub fn delete( + entry: Content, + _entry_header: ChainHeader, + validation_data: ValidationDaa, +) -> Result<(), String> { + helper::validate_only_teacher_can_do( + &entry.teacher_address, + validation_data.sources(), + "delete the content", + ) +} + +pub fn section_anchor_to_content_link(validation_data: LinkValidationData) -> Result<(), String> { + match validation_data { + hdk::LinkValidationData::LinkAdd { + link, + validation_data, + } => { + // get author of this entry + let author: HashString = validation_data.package.chain_header.provenances()[0].source(); + // get link base: entry from which the link goes + let base: SectionAnchor = hdk::utils::get_as_type(link.link.base().clone())?; + // get link target: entry to which the link goes + let target: Content = hdk::utils::get_as_type(link.link.target().clone())?; + if base.teacher_address != target.teacher_address { + return Err(String::from( + "Can't link SectionAnchor to Content because their teacher addresses are different", + )); + } else if author != base.teacher_address { + return Err(String::from( + "Can't link SectionAnchor to Content because your address isn't specified as teacher address for this content", + )); + } + Ok(()) + } + hdk::LinkValidationData::LinkRemove { + link, + validation_data, + } => { + // get author of this entry + let author: HashString = validation_data.package.chain_header.provenances()[0].source(); + // get link base: entry from which the link goes + let base: SectionAnchor = hdk::utils:.get_as_type(address: link.link.base().clone())?; + if author != base.teacher_address { + return Err(String::from( + "Can't remove link from SectionAnchor to Content because your address isn't specified as teacher_address for this course", + )); + } + Ok(()) + } + } +}