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

ambee/giterated

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

Huge refactor to prep for moving the daemon over to the plugin architecture

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5df753c

⁨giterated-plugins/giterated-protocol/src/lib.rs⁩ - ⁨7098⁩ bytes
Raw
1 use std::{str::FromStr, sync::Arc};
2
3 use giterated_models::{
4 authenticated::{InstanceSignature, UserAuthenticationToken},
5 instance::Instance,
6 object::GiteratedObject,
7 operation::GiteratedOperation,
8 user::User,
9 };
10 use handlers::{NetworkedObject, NetworkedOperation};
11 use object::NetworkAnyObject;
12 use operations::NetworkAnyOperation;
13 use rsa::{
14 pkcs1::DecodeRsaPrivateKey,
15 pss::SigningKey,
16 sha2::Sha256,
17 signature::{RandomizedSigner, SignatureEncoding},
18 RsaPrivateKey,
19 };
20 use serde::{Deserialize, Serialize};
21 use std::fmt::Debug;
22
23 pub mod handlers;
24 pub mod object;
25 pub mod operations;
26
27 #[macro_use]
28 extern crate tracing;
29
30 #[derive(Clone)]
31 pub struct NetworkOperationState {
32 authentication: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
33 }
34
35 impl NetworkOperationState {
36 pub fn new() -> Self {
37 Self {
38 authentication: vec![],
39 }
40 }
41
42 pub fn authenticate(
43 &mut self,
44 provider: impl AuthenticationSourceProviders + Send + Sync + 'static,
45 ) {
46 self.authentication.push(Arc::new(provider))
47 }
48 }
49
50 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
51 pub struct AuthenticatedPayload {
52 pub source: Vec<AuthenticationSource>,
53 pub object: String,
54 pub operation: String,
55 pub payload: Vec<u8>,
56 }
57
58 impl AuthenticatedPayload {
59 pub fn into_message(self) -> GiteratedMessage<NetworkedObject, NetworkedOperation> {
60 GiteratedMessage {
61 object: NetworkedObject::from_str(&self.object).unwrap(),
62 operation: self.operation,
63 payload: serde_json::from_slice(&self.payload).unwrap(),
64 }
65 }
66 }
67
68 pub trait AuthenticationSourceProvider: Debug {
69 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
70 }
71
72 pub trait AuthenticationSourceProviders: Debug {
73 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
74 }
75
76 impl<A> AuthenticationSourceProviders for A
77 where
78 A: AuthenticationSourceProvider,
79 {
80 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
81 vec![self.authenticate(payload)]
82 }
83 }
84
85 impl<A, B> AuthenticationSourceProviders for (A, B)
86 where
87 A: AuthenticationSourceProvider,
88 B: AuthenticationSourceProvider,
89 {
90 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
91 let (first, second) = self;
92
93 vec![first.authenticate(payload), second.authenticate(payload)]
94 }
95 }
96
97 #[derive(Clone, Debug)]
98 pub struct UserAuthenticator {
99 pub user: User,
100 pub token: UserAuthenticationToken,
101 }
102
103 impl AuthenticationSourceProvider for UserAuthenticator {
104 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
105 AuthenticationSource::User {
106 user: self.user.clone(),
107 token: self.token.clone(),
108 }
109 }
110 }
111
112 #[derive(Debug, Clone)]
113 pub struct InstanceAuthenticator {
114 pub instance: Instance,
115 pub private_key: String,
116 }
117
118 impl AuthenticationSourceProvider for InstanceAuthenticator {
119 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
120 let mut rng = rand::thread_rng();
121
122 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
123 let signing_key = SigningKey::<Sha256>::new(private_key);
124 let signature = signing_key.sign_with_rng(&mut rng, payload);
125
126 AuthenticationSource::Instance {
127 instance: self.instance.clone(),
128 // TODO: Actually parse signature from private key
129 signature: InstanceSignature(signature.to_bytes().into_vec()),
130 }
131 }
132 }
133
134 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
135 pub enum AuthenticationSource {
136 User {
137 user: User,
138 token: UserAuthenticationToken,
139 },
140 Instance {
141 instance: Instance,
142 signature: InstanceSignature,
143 },
144 }
145
146 #[derive(Serialize)]
147 #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation<O>"))]
148 pub struct GiteratedMessage<O: GiteratedObject, V: GiteratedOperation<O>> {
149 #[serde(with = "string")]
150 pub object: O,
151 pub operation: String,
152 pub payload: V,
153 }
154
155 #[allow(unused)]
156 mod string {
157 use std::fmt::Display;
158 use std::str::FromStr;
159
160 use serde::{de, Deserialize, Deserializer, Serializer};
161
162 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
163 where
164 T: Display,
165 S: Serializer,
166 {
167 serializer.collect_str(value)
168 }
169
170 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
171 where
172 T: FromStr,
173 T::Err: Display,
174 D: Deserializer<'de>,
175 {
176 String::deserialize(deserializer)?
177 .parse()
178 .map_err(de::Error::custom)
179 }
180 }
181
182 impl GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
183 pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
184 &self,
185 ) -> Result<GiteratedMessage<O, V>, ()> {
186 let object = O::from_object_str(&self.object.0).map_err(|_| ())?;
187 let payload = serde_json::from_slice::<V>(&self.payload.0).map_err(|_| ())?;
188
189 Ok(GiteratedMessage {
190 object,
191 operation: self.operation.clone(),
192 payload,
193 })
194 }
195 }
196
197 impl<V: GiteratedOperation<O> + Debug, O: GiteratedObject + Debug> Debug
198 for GiteratedMessage<O, V>
199 {
200 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
201 f.debug_struct("GiteratedMessage")
202 .field("object", &self.object)
203 .field("operation", &self.operation)
204 .field("payload", &self.payload)
205 .finish()
206 }
207 }
208
209 #[derive(Debug, Clone, thiserror::Error)]
210 #[error("a remote internal error occurred")]
211 pub struct RemoteError;
212
213 #[derive(Debug, thiserror::Error)]
214 #[error("a remote internal error occurred")]
215
216 pub struct NetworkError;
217
218 #[derive(Debug)]
219 pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
220 pub source: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
221 pub message: GiteratedMessage<O, D>,
222 }
223
224 impl<O: GiteratedObject, D: GiteratedOperation<O>> Authenticated<O, D> {
225 pub fn new(message: GiteratedMessage<O, D>) -> Self {
226 Self {
227 source: vec![],
228 message,
229 }
230 }
231
232 pub fn append_authentication(
233 &mut self,
234 authentication: Arc<dyn AuthenticationSourceProviders + Send + Sync>,
235 ) {
236 self.source.push(authentication);
237 }
238
239 pub fn into_payload(mut self) -> AuthenticatedPayload {
240 let payload = serde_json::to_vec(&self.message.payload).unwrap();
241
242 AuthenticatedPayload {
243 object: self.message.object.to_string(),
244 operation: self.message.operation,
245 source: self
246 .source
247 .drain(..)
248 .map(|provider| provider.as_ref().authenticate_all(&payload))
249 .flatten()
250 .collect::<Vec<_>>(),
251 payload,
252 }
253 }
254 }
255
256 #[derive(Clone, Debug)]
257 pub struct ProtocolState {
258 pub home_uri: Option<String>,
259 }
260