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// }