MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / score

Method score

nodedb/src/control/security/risk.rs:85–142  ·  view source on GitHub ↗

Score a request based on context signals. Returns (score, decision, triggered_signals).

(
        &self,
        user_id: &str,
        client_ip: &str,
        auth_ctx: &super::auth_context::AuthContext,
    )

Source from the content-addressed store, hash-verified

83 ///
84 /// Returns (score, decision, triggered_signals).
85 pub fn score(
86 &self,
87 user_id: &str,
88 client_ip: &str,
89 auth_ctx: &super::auth_context::AuthContext,
90 ) -> (f64, RiskDecision, Vec<String>) {
91 let mut total = 0.0_f64;
92 let mut signals = Vec::new();
93
94 // Signal: new_ip.
95 if self.is_new_ip(user_id, client_ip)
96 && let Some(&w) = self.config.weights.get("new_ip")
97 {
98 total += w;
99 signals.push("new_ip".into());
100 }
101
102 // Signal: unusual_time (outside 06:00-22:00 local).
103 let hour = current_hour();
104 if !(6..22).contains(&hour)
105 && let Some(&w) = self.config.weights.get("unusual_time")
106 {
107 total += w;
108 signals.push("unusual_time".into());
109 }
110
111 // Signal: high_privilege (superuser or tenant_admin).
112 if (auth_ctx.is_superuser() || auth_ctx.roles.iter().any(|r| r == "tenant_admin"))
113 && let Some(&w) = self.config.weights.get("high_privilege")
114 {
115 total += w;
116 signals.push("high_privilege".into());
117 }
118
119 // Signal: device_not_trusted.
120 if auth_ctx
121 .metadata
122 .get("device_trusted")
123 .is_none_or(|v| v != "true")
124 && let Some(&w) = self.config.weights.get("device_not_trusted")
125 {
126 total += w;
127 signals.push("device_not_trusted".into());
128 }
129
130 // Record this IP as known for future requests.
131 self.record_ip(user_id, client_ip);
132
133 let decision = if total <= self.config.allow_threshold {
134 RiskDecision::Allow
135 } else if total >= self.config.deny_threshold {
136 RiskDecision::Deny
137 } else {
138 RiskDecision::StepUpMfa
139 };
140
141 (total, decision, signals)
142 }

Callers 3

new_ip_triggersFunction · 0.45
high_privilege_triggersFunction · 0.45
thresholdsFunction · 0.45

Calls 8

current_hourFunction · 0.85
is_new_ipMethod · 0.80
is_superuserMethod · 0.80
record_ipMethod · 0.80
getMethod · 0.45
pushMethod · 0.45
containsMethod · 0.45
iterMethod · 0.45

Tested by 3

new_ip_triggersFunction · 0.36
high_privilege_triggersFunction · 0.36
thresholdsFunction · 0.36