nio_client/
auth.rs

1use tonic::Status;
2
3#[derive(Debug)]
4pub struct Principal(String);
5
6impl Principal {
7    pub fn as_str(&self) -> &str {
8        self.0.as_str()
9    }
10}
11
12impl AsRef<str> for Principal {
13    fn as_ref(&self) -> &str {
14        self.0.as_ref()
15    }
16}
17
18impl From<String> for Principal {
19    fn from(value: String) -> Self {
20        Principal(value)
21    }
22}
23
24impl From<Principal> for String {
25    #[inline]
26    fn from(value: Principal) -> String {
27        value.0
28    }
29}
30
31impl From<&Principal> for String {
32    #[inline]
33    fn from(value: &Principal) -> String {
34        value.0.clone()
35    }
36}
37
38pub enum CheckResult {
39    Ok(Principal),
40    Forbidden(Principal),
41    UnknownPutativeUser,
42}
43
44
45// impl TryFrom<String> for CheckResult {
46//     type Error = ParseError;
47//
48//     fn try_from(value: String) -> Result<Self, Self::Error> {
49//         Ok(CheckResult::Principal(Principal(value)))
50//     }
51// }
52
53
54#[derive(thiserror::Error, Debug)]
55pub enum CallError {
56    #[error("unexpected response format")]
57    UnexpectedResponseFormat,
58    #[error("call error: {0}")]
59    Status(#[from] Status),
60}
61
62// #[derive(thiserror::Error, Debug)]
63// pub enum AuthError {
64//     SessionMissing,
65//     //InternalServerError(Box<dyn Error>),
66//     InternalServerError,
67//     Forbidden,
68//     BadRequest,
69// }
70
71// impl warp::reject::Reject for AuthError {}
72
73// pub trait AuthChecker: Clone + Send {
74//     async fn check(
75//         &mut self,
76//         namespaces: Namespace,
77//         obj: Obj,
78//         permission: Permission,
79//         user_id: UserId,
80//     ) -> Result<CheckResult, CallError>;
81// }
82//
83// pub fn uri() -> impl Filter<Extract = (Uri,), Error = Infallible> + Clone {
84//     warp::path::full()
85//         .and(
86//             // Optional query string. See https://github.com/seanmonstar/warp/issues/86
87//             query::raw().or(warp::any().map(String::default)).unify(),
88//         )
89//         .map(|path: FullPath, query: String| {
90//             let pq = match query.as_str() {
91//                 "" => PathAndQuery::try_from(path.as_str())
92//                     .unwrap_or_else(|_| PathAndQuery::from_static("/")),
93//                 qs => PathAndQuery::try_from(format!("{}?{}", path.as_str(), qs))
94//                     .unwrap_or_else(|_| PathAndQuery::from_static("/")),
95//             };
96//             Uri::from(pq)
97//         })
98// }
99//
100// fn cookie() -> impl Filter<Extract = (String,), Error = Rejection> + Clone {
101//     const SESSION_COOKIE: &str = "session";
102//     warp::any()
103//         .and(warp::cookie::optional(SESSION_COOKIE))
104//         .and(uri())
105//         .and_then(
106//             move |maybe_value: Option<String>, uri: Uri| match maybe_value {
107//                 Some(value) => future::ready(Ok(value)),
108//                 None => future::ready(Err(AuthError::SessionMissing)),
109//             },
110//         )
111// }
112
113// pub fn authorize<A: AuthChecker>(
114//     checker: A,
115//     namespaces: Namespace,
116//     obj: Option<Obj>,
117//     permission: Permission,
118// ) -> impl Filter<Extract = ((),), Error = Rejection> + Clone {
119//     cookie()
120//         .and(with_one(namespaces.clone()))
121//         .and(with_one(obj.clone()))
122//         .and(with_one(permission.clone()))
123//         .and(with_one(checker.clone()))
124//         .and_then(|token: String, namespaces, obj, permission, cc: A| async {
125//             let user_id = UserId::try_from(token).map_err(|err| AuthError::BadRequest)?;
126//             let mut cc = cc;
127//             match cc
128//                 .check(namespaces, Obj(String::default()), permission, user_id)
129//                 .await
130//             {
131//                 Err(err) => Err(AuthError::InternalServerError.into()), //(Box::new(err)).into()),
132//                 //Ok(CheckResult::Principal(principal)) => Ok(principal),
133//                 Ok(CheckResult::Principal(_)) => Ok(()),
134//                 Ok(CheckResult::Forbidden) => Err(AuthError::Forbidden.into()),
135//             }
136//         })
137// }
138//
139// pub fn authorize2(
140//     agent: impl AuthChecker,
141//     namespaces: Namespace,
142//     obj: Option<Obj>,
143//     permission: Permission,
144// ) -> impl Filter<Extract = (Principal,), Error = Infallible> + Clone {
145//     warp::any().map(|| Principal(String::default()))
146// }
147//
148// async fn check<A: AuthChecker>(
149//     token: String,
150//     namespaces: Namespace,
151//     obj: Option<Obj>,
152//     permission: Permission,
153//     cc: A,
154// ) -> Result<(), Rejection> {
155//     let user_id = UserId::try_from(token).map_err(|err| AuthError::BadRequest)?;
156//     let mut cc = cc;
157//     match cc
158//         .check(namespaces, Obj(String::default()), permission, user_id)
159//         .await
160//     {
161//         Err(err) => Err(AuthError::InternalServerError.into()), //(Box::new(err)).into()),
162//         //Ok(CheckResult::Principal(principal)) => Ok(principal),
163//         Ok(CheckResult::Principal(_)) => Ok(()),
164//         Ok(CheckResult::Forbidden) => Err(AuthError::Forbidden.into()),
165//     }
166// }