asteroid_mq/protocol/node/edge/
auth.rs1use std::{borrow::Cow, future::Future, sync::Arc};
2
3use crate::prelude::NodeId;
4
5use super::EdgeRequestEnum;
6#[derive(Clone)]
7pub struct EdgeAuthService {
8 inner: Arc<dyn sealed::BoxedEdgeAuth>,
9 source: Cow<'static, str>,
10}
11
12impl std::fmt::Debug for EdgeAuthService {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 f.debug_struct("EdgeAuthService")
15 .field("source", &self.source)
16 .finish()
17 }
18}
19
20impl std::fmt::Display for EdgeAuthService {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 write!(f, "EdgeAuthService: {}", self.source)
23 }
24}
25
26#[derive(Debug)]
27pub struct EdgeAuthError {
28 reason: Cow<'static, str>,
29 source: Option<Box<dyn std::error::Error + Send + Sync>>,
30}
31
32impl EdgeAuthError {
33 pub fn new<E: std::error::Error + Send + Sync + 'static>(
34 reason: impl Into<Cow<'static, str>>,
35 source: E,
36 ) -> Self {
37 Self {
38 reason: reason.into(),
39 source: Some(Box::new(source)),
40 }
41 }
42 pub fn new_local(reason: impl Into<Cow<'static, str>>) -> Self {
43 Self {
44 reason: reason.into(),
45 source: None,
46 }
47 }
48}
49impl std::fmt::Display for EdgeAuthError {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 write!(f, "EdgeAuthError: {}", self.reason,)?;
52 if let Some(source) = &self.source {
53 write!(f, "with source: {}", source)?;
54 }
55 Ok(())
56 }
57}
58
59impl EdgeAuthService {
60 pub fn new<T>(inner: T) -> Self
61 where
62 T: EdgeAuth,
63 {
64 Self {
65 inner: Arc::new(inner),
66 source: std::any::type_name::<T>().into(),
67 }
68 }
69
70 pub async fn check(
71 &self,
72 from: NodeId,
73 request: &EdgeRequestEnum,
74 ) -> Result<(), EdgeAuthError> {
75 self.inner.check(from, request).await
76 }
77}
78
79pub trait EdgeAuth: Send + Sync + 'static {
80 fn check<'r>(
81 &'r self,
82 from: NodeId,
83 request: &'r EdgeRequestEnum,
84 ) -> impl Future<Output = Result<(), EdgeAuthError>> + Send + 'r;
85}
86
87mod sealed {
88 use futures_util::future::BoxFuture;
89
90 use super::{EdgeAuth, EdgeAuthError};
91 use crate::protocol::node::edge::EdgeRequestEnum;
92 use crate::protocol::node::NodeId;
93
94 pub(super) trait BoxedEdgeAuth: Send + Sync {
95 fn check<'r>(
96 &'r self,
97 from: NodeId,
98 request: &'r EdgeRequestEnum,
99 ) -> BoxFuture<'r, Result<(), EdgeAuthError>>;
100 }
101
102 impl<T> BoxedEdgeAuth for T
103 where
104 T: EdgeAuth,
105 {
106 fn check<'r>(
107 &'r self,
108 from: NodeId,
109 request: &'r EdgeRequestEnum,
110 ) -> BoxFuture<'r, Result<(), EdgeAuthError>> {
111 Box::pin(async move { self.check(from, request).await })
112 }
113 }
114}