# holochain_roles Generic holochain mixin to include administrator and dynamic roles in any holochain application, using the progenitor pattern. This mixin is built to target `hc v0.0.42-alpha3`. It also depends on the [holochain_anchors](https://github.com/holochain/holochain_anchors) to be present and configured. ## Design Here is the design for this mixin: https://hackmd.io/6xfwfSVYSGeZe3vQ_-1cWw?view. ## Documentation Here you can find the documentation for this mixin: https://docs.rs/holochain_roles. ## Installation Add the following to your zomes cargo toml. ``` holochain_anchors = "0.2.1" holochain_roles = "0.1.7" ``` ## Usage ### Setup Add the anchor entry definition to your zome. ```rust #[entry_def] fn anchor_def() -> ValidatingEntryType { holochain_anchors::anchor_definition() } ``` Add the roles entry definition to your zome. ```rust #[entry_def] fn roles_def() -> ValidatingEntryType { holochain_roles::role_assignment_entry_def() } ``` ### Assign a role To assign a role, simply call the `assign_role` function: ```rust #[zome_fn("hc_public")] fn some_other_public_function(agent_address: Address) { let my_role_name = String::from("editor"); holochain_roles::handlers::assign_role(&my_role_name, &agent_address)?; ... } ``` ### Assign an administrator Only agents that have the administrator role or the progenitor of the DNA can assign or unassign roles. To assign an administrator role, call the `assign_role` function with the imported administrator role name: ```rust #[zome_fn("hc_public")] fn some_other_public_function(agent_address: Address) { let my_role_name = String::from(holochain_roles::ADMIN_ROLE_NAME); holochain_roles::handlers::assign_role(&my_role_name, &agent_address)?; ... } ``` ### Check if user currently has a certain role To check if a user has a certain role, you can use the validation `has_agent_role` function: ```rust validation: | _validation_data: hdk::EntryValidationData| { match _validation_data { hdk::EntryValidationData::Create { entry, validation_data } => { let agent_address = &validation_data.sources()[0]; let is_agent_permitted_to_create_this_entry = holochain_roles::validaton::has_agent_role(&agent_address, String::from("editor"))?; if !is_agent_permitted_to_create_this_entry { return Err(String::from("Only editors can create a new entry")); } ... } } } ``` ### Check if user had a certain role in a certain moment in time To check if a user has a certain role, you have two options: - Use the validation `validate_required_role` function, which will return and error in case the user did not have the given role at the time they committed the entry: ```rust validation: | _validation_data: hdk::EntryValidationData| { match _validation_data { hdk::EntryValidationData::Create { validation_data } => { holochain_roles::validaton::validate_require_role(&validation_data, String::from("editor"))?; ... } } } ``` - Use the validation `has_agent_role` function: ```rust validation: | _validation_data: hdk::EntryValidationData| { match _validation_data { hdk::EntryValidationData::Create { entry, validation_data } => { let agent_address = &validation_data.sources()[0]; let timestamp = &validation_data.package.chain_header.timestamp(); let is_agent_permitted_to_create_this_entry = holochain_roles::validaton::had_agent_role(&agent_address, String::from("editor"), timestamp)?; if !is_agent_permitted_to_create_this_entry { return Err(String::from("Only editors can create a new entry")); } ... } } } ``` ### Get all role assignments for an agent To get all role assignments for a certain agent, you can use the validation `get_agent_roles` function: ```rust #[zome_fn("hc_public")] fn some_public_function(agent_address: Address) { let roles: Vec = holochain_roles::handlers::get_agent_roles(&agent_address)?; } ``` ### Get all agents that have a certain role assigned To get all role assignments for a certain agent, you can use the validation `get_role_agents` function: ```rust #[zome_fn("hc_public")] fn some_public_function(role_name: String) { let agents: Vec
= holochain_roles::handlers::get_role_agents(&role_name)?; } ``` ### Unassign a role To unassign a role, simply call the `unassign_role` function: ```rust #[zome_fn("hc_public")] fn some_other_public_function(agent_address: Address) { let my_role_name = String::from("editor"); holochain_roles::handlers::unassign_role(&my_role_name, &agent_address)?; ... } ```