ockam_core/access_control/
source.rs

1use crate::compat::boxed::Box;
2use crate::compat::vec::Vec;
3use crate::{async_trait, Address, IncomingAccessControl, RelayMessage, Result};
4
5/// An Access Control type that allows messages from the given source address to go through
6/// Note that it's based on source address, not a first hop of return_route, which may be different
7/// in some scenarios
8#[derive(Debug)]
9pub struct AllowSourceAddress(pub Address);
10
11impl AllowSourceAddress {
12    /// Convenience constructor
13    pub fn new(address: impl Into<Address>) -> Self {
14        Self(address.into())
15    }
16}
17
18#[async_trait]
19impl IncomingAccessControl for AllowSourceAddress {
20    async fn is_authorized(&self, relay_msg: &RelayMessage) -> Result<bool> {
21        if &self.0 == relay_msg.source() {
22            crate::allow()
23        } else {
24            crate::deny()
25        }
26    }
27}
28
29/// An Access Control type that allows messages from the given source addresses to go through
30/// Note that it's based on source address, not a first hop of return_route, which may be different
31/// in some scenarios
32#[derive(Debug)]
33pub struct AllowSourceAddresses(pub Vec<Address>);
34
35#[async_trait]
36impl IncomingAccessControl for AllowSourceAddresses {
37    async fn is_authorized(&self, relay_msg: &RelayMessage) -> Result<bool> {
38        if self.0.contains(relay_msg.source()) {
39            crate::allow()
40        } else {
41            crate::deny()
42        }
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::compat::future::poll_once;
49    use crate::{
50        route, Address, AllowSourceAddress, AllowSourceAddresses, IncomingAccessControl,
51        LocalMessage, RelayMessage, Result,
52    };
53
54    #[test]
55    fn test_1_address() -> Result<()> {
56        // Testing situation when source and return addresses are different
57        let source_address = Address::random_local();
58        let return_address = Address::random_local();
59        let onward_address = Address::random_local();
60
61        let ac = AllowSourceAddress(source_address.clone());
62
63        let msg = LocalMessage::new()
64            .with_onward_route(route![onward_address.clone()])
65            .with_return_route(route![return_address.clone()]);
66        let msg = RelayMessage::new(source_address.clone(), onward_address.clone(), msg);
67
68        assert!(poll_once(async { ac.is_authorized(&msg).await })?);
69
70        let msg = LocalMessage::new()
71            .with_onward_route(route![onward_address.clone()])
72            .with_return_route(route![source_address]);
73        let msg = RelayMessage::new(return_address, onward_address, msg);
74
75        assert!(!poll_once(async { ac.is_authorized(&msg).await })?);
76
77        Ok(())
78    }
79
80    #[test]
81    fn test_2_addresses() -> Result<()> {
82        // Testing situation when source and return addresses are different
83        let source_address1 = Address::random_local();
84        let source_address2 = Address::random_local();
85        let return_address = Address::random_local();
86        let onward_address = Address::random_local();
87
88        let ac = AllowSourceAddresses(vec![source_address1.clone(), source_address2.clone()]);
89
90        let msg = LocalMessage::new()
91            .with_onward_route(route![onward_address.clone()])
92            .with_return_route(route![return_address.clone()]);
93        let msg = RelayMessage::new(source_address1.clone(), onward_address.clone(), msg);
94
95        assert!(poll_once(async { ac.is_authorized(&msg).await })?);
96
97        let msg = LocalMessage::new()
98            .with_onward_route(route![onward_address.clone()])
99            .with_return_route(route![return_address.clone()]);
100
101        let msg = RelayMessage::new(source_address2, onward_address.clone(), msg);
102
103        assert!(poll_once(async { ac.is_authorized(&msg).await })?);
104
105        let msg = LocalMessage::new()
106            .with_onward_route(route![onward_address.clone()])
107            .with_return_route(route![source_address1]);
108
109        let msg = RelayMessage::new(return_address, onward_address, msg);
110
111        assert!(!poll_once(async { ac.is_authorized(&msg).await })?);
112
113        Ok(())
114    }
115}