dpp_crypto/access/
filter.rs1use dpp_domain::AccessTier;
4
5use super::policy::SectorAccessPolicy;
6
7#[derive(Debug, Clone)]
9pub struct PolicyDecision {
10 pub granted_tier: AccessTier,
12 pub redacted_fields: Vec<String>,
14 pub filtered_data: serde_json::Value,
16}
17
18pub fn filter_by_access_tier(
29 data: &serde_json::Value,
30 policy: &SectorAccessPolicy,
31 caller_tier: AccessTier,
32) -> PolicyDecision {
33 let mut redacted_fields = Vec::new();
34 let filtered_data = filter_value(data, policy, caller_tier, "", &mut redacted_fields);
35 PolicyDecision {
36 granted_tier: caller_tier,
37 redacted_fields,
38 filtered_data,
39 }
40}
41
42fn filter_value(
43 data: &serde_json::Value,
44 policy: &SectorAccessPolicy,
45 caller_tier: AccessTier,
46 prefix: &str,
47 redacted: &mut Vec<String>,
48) -> serde_json::Value {
49 match data {
50 serde_json::Value::Object(map) => {
51 let mut filtered = serde_json::Map::new();
52 for (key, value) in map {
53 let path = if prefix.is_empty() {
54 key.clone()
55 } else {
56 format!("{prefix}.{key}")
57 };
58 if caller_tier >= policy.tier_for_field(key) {
59 filtered.insert(
60 key.clone(),
61 filter_value(value, policy, caller_tier, &path, redacted),
62 );
63 } else {
64 redacted.push(path);
65 }
66 }
67 serde_json::Value::Object(filtered)
68 }
69 serde_json::Value::Array(items) => serde_json::Value::Array(
70 items
71 .iter()
72 .enumerate()
73 .map(|(i, v)| {
74 filter_value(v, policy, caller_tier, &format!("{prefix}[{i}]"), redacted)
75 })
76 .collect(),
77 ),
78 other => other.clone(),
79 }
80}