pub struct RouteIpGate { /* private fields */ }Expand description
The route-level IP gate: a route decorator’s ip_whitelist and
ip_blacklist (RouteConfig.ip_whitelist / .ip_blacklist).
This is the Rust family’s port of the reference engine’s route IP stage
(guard_core/core/checks/helpers.py::check_route_ip_access, the IP-list
arms; the Go and PHP family ports run the same order). One call,
RouteIpGate::evaluate, decides a request IP against one route:
whitelist configured, match: pass the route stage (the whitelist verdict
wins, even over a blacklist match)
whitelist configured, miss: deny (the whitelist takes over the route
verdict; the blacklist is never consulted)
blacklist match: deny
neither list configured: unrestricted (the global gate decides)The precedence is the reference’s check_route_ip_access: the whitelist
is asked first and its answer settles the IP verdict (ip_result); the
blacklist is only consulted when the whitelist gives no verdict (it is
not configured), so a whitelisted IP that is also blacklisted still
passes the route stage.
Matching semantics are the global gate’s (IpGateConfig): a bare IP or
a CIDR range per entry, IPv4-mapped request addresses canonicalized,
families never crossing. Invalid entries are config errors:
RouteIpGate::new fails closed.
The global lists are still enforced afterwards by the caller, so a route whitelist match never relaxes the global gate; it only clears the route verdict.
§Example
use std::net::IpAddr;
use std::str::FromStr;
use guard_core_engine::ip_gate::{RouteIpGate, RouteIpVerdict};
let gate = RouteIpGate::new(["192.0.2.40"], ["203.0.113.9"]).expect("valid lists");
// A whitelist member passes the route stage, even a blacklisted one:
// the whitelist verdict wins over the blacklist.
assert_eq!(
gate.evaluate(IpAddr::from_str("192.0.2.40").unwrap()),
RouteIpVerdict::Allowed
);
// Everyone else on the route is denied: the whitelist takes over.
assert_eq!(
gate.evaluate(IpAddr::from_str("192.0.2.11").unwrap()),
RouteIpVerdict::Denied
);
// A blacklisted IP outside the whitelist is denied.
assert_eq!(
gate.evaluate(IpAddr::from_str("203.0.113.9").unwrap()),
RouteIpVerdict::Denied
);
// No lists: the route leaves the request to the global gate.
let open = RouteIpGate::new([] as [&str; 0], [] as [&str; 0]).expect("valid lists");
assert_eq!(
open.evaluate(IpAddr::from_str("192.0.2.11").unwrap()),
RouteIpVerdict::Unrestricted
);Implementations§
Source§impl RouteIpGate
impl RouteIpGate
Sourcepub fn new<W, B>(whitelist: W, blacklist: B) -> Result<Self, IpGateError>
pub fn new<W, B>(whitelist: W, blacklist: B) -> Result<Self, IpGateError>
Parse the route’s two lists, failing closed on the first invalid
entry (the list names in the error are ip_whitelist and
ip_blacklist).
§Errors
Returns an IpGateError naming the list and the first entry that is
neither a valid IP nor a valid CIDR range.
Sourcepub const fn whitelist_configured(&self) -> bool
pub const fn whitelist_configured(&self) -> bool
Whether a route whitelist is configured (non-empty). The reference
_route_overrides_ip_lists: a configured route whitelist also
overrides the global IP lists for the request, so the caller skips
the global gate’s deny paths.
Sourcepub fn evaluate(&self, ip: IpAddr) -> RouteIpVerdict
pub fn evaluate(&self, ip: IpAddr) -> RouteIpVerdict
Evaluate a request IP against the route’s lists: a configured
whitelist takes over the route verdict first (a match passes, a miss
denies, exactly the reference’s ip_result order), then the
blacklist denies, and no list leaves the request unrestricted.
Source§impl RouteIpGate
impl RouteIpGate
Sourcepub fn evaluate_access(
&self,
ip: Option<IpAddr>,
countries: &CountryGate,
handler: Option<&dyn GeoIpHandler>,
) -> RouteAccess
pub fn evaluate_access( &self, ip: Option<IpAddr>, countries: &CountryGate, handler: Option<&dyn GeoIpHandler>, ) -> RouteAccess
The full reference check_route_ip_access: the IP-list verdict
combined with the route’s country verdict
(check_route_country). Denied if either arm is false,
Allowed if either is true, otherwise Unrestricted, so a route
whitelist match no longer overrides a blocked country.
ip is None for the unknown client identity: it is denied when
the route configures an ip_whitelist or a whitelist_countries
and unrestricted otherwise (the reference
_route_whitelist_configured). countries carries the route’s
blocked_countries / whitelist_countries; no handler leaves the
country arm without a verdict.
Trait Implementations§
Source§impl Clone for RouteIpGate
impl Clone for RouteIpGate
Source§impl Debug for RouteIpGate
impl Debug for RouteIpGate
Source§impl Default for RouteIpGate
impl Default for RouteIpGate
impl Eq for RouteIpGate
Source§impl PartialEq for RouteIpGate
impl PartialEq for RouteIpGate
impl StructuralPartialEq for RouteIpGate
Auto Trait Implementations§
impl Freeze for RouteIpGate
impl RefUnwindSafe for RouteIpGate
impl Send for RouteIpGate
impl Sync for RouteIpGate
impl Unpin for RouteIpGate
impl UnsafeUnpin for RouteIpGate
impl UnwindSafe for RouteIpGate
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.