JavaScript is disabled, refresh for a better experience. ambee/giterated-api

ambee/giterated-api

Git repository hosting, collaboration, and discovery for the Fediverse.

Add authentication back into the API

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c3639d1

⁨src/daemon_backend.rs⁩ - ⁨4711⁩ bytes
Raw
1 use std::{fmt::Debug, sync::Arc};
2
3 use futures_util::{SinkExt, StreamExt};
4 use giterated_models::{
5 authenticated::{Authenticated, AuthenticationSourceProviders},
6 error::OperationError,
7 message::GiteratedMessage,
8 object::{GiteratedObject, Object, ObjectRequest, ObjectRequestError, ObjectResponse},
9 object_backend::ObjectBackend,
10 operation::GiteratedOperation,
11 };
12 use serde::de::DeserializeOwned;
13 use tokio_tungstenite::tungstenite::Message;
14
15 use crate::{DaemonConnectionPool, Socket};
16
17 #[derive(Clone)]
18 pub struct NetworkOperationState {
19 authentication: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
20 }
21
22 impl NetworkOperationState {
23 pub fn new() -> Self {
24 Self {
25 authentication: vec![],
26 }
27 }
28
29 pub fn authenticate<S: AuthenticationSourceProviders + Send + Sync + 'static>(
30 &mut self,
31 source: S,
32 ) {
33 self.authentication.push(Arc::new(source))
34 }
35 }
36
37 #[async_trait::async_trait]
38 impl ObjectBackend<NetworkOperationState> for DaemonConnectionPool {
39 async fn object_operation<O: GiteratedObject + Debug, D: GiteratedOperation<O> + Debug>(
40 &self,
41 object: O,
42 operation: &str,
43 payload: D,
44 operation_state: &NetworkOperationState,
45 ) -> Result<D::Success, OperationError<D::Failure>> {
46 let message = GiteratedMessage {
47 object,
48 operation: operation.to_string(),
49 payload,
50 };
51
52 let mut connection = self
53 .0
54 .get()
55 .await
56 .map_err(|e| OperationError::Internal(e.to_string()))?;
57
58 let mut authenticated = Authenticated::new(message);
59 for authentication in &operation_state.authentication {
60 authenticated.append_authentication(authentication.clone());
61 }
62
63 send_expect(&mut connection, authenticated).await
64 }
65
66 async fn get_object<O: GiteratedObject + Debug>(
67 &self,
68 object_str: &str,
69 operation_state: &NetworkOperationState,
70 ) -> Result<Object<NetworkOperationState, O, Self>, OperationError<ObjectRequestError>> {
71 let operation = ObjectRequest(object_str.to_string());
72 info!("Get object: {:?}", operation);
73 let message = GiteratedMessage {
74 object: self.0.manager().target_instance.clone(),
75 operation: ObjectRequest::operation_name().to_string(),
76 payload: operation,
77 };
78
79 let mut connection = self
80 .0
81 .get()
82 .await
83 .map_err(|e| OperationError::Internal(e.to_string()))?;
84
85 let mut authenticated = Authenticated::new(message);
86 for authentication in &operation_state.authentication {
87 authenticated.append_authentication(authentication.clone());
88 }
89
90 let object_raw: ObjectResponse = send_expect(&mut connection, authenticated).await?;
91 Ok(unsafe {
92 Object::new_unchecked(
93 O::from_str(&object_raw.0)
94 .map_err(|_e| OperationError::Internal("heck".to_string()))?,
95 self.clone(),
96 )
97 })
98 }
99 }
100
101 async fn send_expect<
102 O: GiteratedObject,
103 D: GiteratedOperation<O>,
104 B: DeserializeOwned,
105 R: DeserializeOwned,
106 >(
107 socket: &mut Socket,
108 message: Authenticated<O, D>,
109 ) -> Result<R, OperationError<B>> {
110 let payload = bincode::serialize(&message.into_payload()).unwrap();
111
112 socket
113 .send(Message::Binary(payload))
114 .await
115 .map_err(|e| OperationError::Internal(e.to_string()))?;
116
117 while let Some(message) = socket.next().await {
118 let payload = match message.map_err(|e| OperationError::Internal(e.to_string()))? {
119 Message::Binary(payload) => payload,
120 _ => {
121 continue;
122 }
123 };
124
125 let raw_result = bincode::deserialize::<Result<Vec<u8>, OperationError<Vec<u8>>>>(&payload)
126 .map_err(|e| OperationError::Internal(e.to_string()))?;
127
128 // Map ok
129 let raw_result = match raw_result {
130 Ok(raw) => Ok(serde_json::from_slice(&raw)
131 .map_err(|e| OperationError::Internal(e.to_string()))?),
132 Err(err) => Err(match err {
133 OperationError::Operation(err) => OperationError::Operation(
134 serde_json::from_slice(&err)
135 .map_err(|e| OperationError::Internal(e.to_string()))?,
136 ),
137 OperationError::Internal(err) => OperationError::Internal(err),
138 OperationError::Unhandled => OperationError::Unhandled,
139 }),
140 };
141
142 return raw_result;
143 }
144
145 panic!()
146 }
147