roles_integrity/
roles.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use hdi::prelude::*;

use crate::LinkTypes;

///Generate the all_roles path
pub fn all_roles_path() -> ExternResult<TypedPath> {
    Path::from("all_roles").typed(LinkTypes::RolesPath)
}

///Generate the path to role (from all_roles)
pub fn role_path(role: &String) -> ExternResult<TypedPath> {
    let all_roles = all_roles_path()?;
    let mut components = all_roles.path.0;
    components.push(Component::from(role));
    Path::from(components).typed(LinkTypes::RolesPath)
}

///Generate the base address for a role based on path
#[hdk_extern]
pub fn role_base_address(role: String) -> ExternResult<EntryHash> {
    role_path(&role)?.path_entry_hash()
}
///Validate the creation correct link paths for role links
pub fn validate_create_link_roles_path(
    _action: CreateLink,
    base_address: AnyLinkableHash,
    target_address: AnyLinkableHash,
    tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
    let Some(base_entry_hash) = base_address.clone().into_entry_hash() else {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "No entry hash associated with link",
        )));
    };
    let Some(target_entry_hash) = target_address.into_entry_hash() else {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "No entry hash associated with link",
        )));
    };

    let all_roles_path_entry_hash = all_roles_path()?.path.path_entry_hash()?;

    if target_entry_hash.eq(&all_roles_path_entry_hash) {
        return Ok(ValidateCallbackResult::Valid);
    }

    if !base_entry_hash.eq(&all_roles_path_entry_hash) {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "RolesPath link must have the all roles path as its base",
        )));
    }

    let bytes = SerializedBytes::from(UnsafeBytes::from(tag.0));
    let Ok(component) = Component::try_from(bytes) else {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "Could not convert bytes to component",
        )));
    };

    let Ok(role) = String::try_from(&component) else {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "Could not convert component from path",
        )));
    };

    if !target_entry_hash.eq(&role_path(&role)?.path_entry_hash()?) {
        return Ok(ValidateCallbackResult::Invalid(String::from(
            "RolesPath link must point to the role path entry hash",
        )));
    }
    Ok(ValidateCallbackResult::Valid)
}

///Validate the path of delete links
pub fn validate_delete_link_roles_path(
    _action: DeleteLink,
    _original_action: CreateLink,
    _base: AnyLinkableHash,
    _target: AnyLinkableHash,
    _tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
    Ok(ValidateCallbackResult::Invalid(String::from(
        "Can't delete roles path links",
    )))
}