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

ambee/giterated

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

More progress :)

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨92c3f32

⁨plugins/giterated-protocol/src/lib.rs⁩ - ⁨7972⁩ bytes
Raw
1 use std::{ops::Deref, 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 StackOperationState {
32 pub our_instance: Instance,
33 pub instance: Option<AuthenticatedInstance>,
34 pub user: Option<AuthenticatedUser>,
35 }
36
37 #[derive(Clone, Debug)]
38 pub struct AuthenticatedInstance(Instance);
39
40 impl AuthenticatedInstance {
41 pub fn new(instance: Instance) -> Self {
42 AuthenticatedInstance(instance)
43 }
44 }
45
46 impl Deref for AuthenticatedInstance {
47 type Target = Instance;
48
49 fn deref(&self) -> &Self::Target {
50 &self.0
51 }
52 }
53
54 #[derive(Clone, Debug)]
55 pub struct AuthenticatedUser(User);
56
57 impl AuthenticatedUser {
58 pub fn new(user: User) -> Self {
59 AuthenticatedUser(user)
60 }
61 }
62
63 impl Deref for AuthenticatedUser {
64 type Target = User;
65
66 fn deref(&self) -> &Self::Target {
67 &self.0
68 }
69 }
70
71 #[derive(Clone)]
72 pub struct NetworkOperationState {
73 authentication: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
74 }
75
76 impl Default for NetworkOperationState {
77 fn default() -> Self {
78 Self::new()
79 }
80 }
81
82 impl NetworkOperationState {
83 pub fn new() -> Self {
84 Self {
85 authentication: vec![],
86 }
87 }
88
89 pub fn authenticate(
90 &mut self,
91 provider: impl AuthenticationSourceProviders + Send + Sync + 'static,
92 ) {
93 self.authentication.push(Arc::new(provider))
94 }
95 }
96
97 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
98 pub struct AuthenticatedPayload {
99 pub source: Vec<AuthenticationSource>,
100 pub object: String,
101 pub operation: String,
102 pub payload: Vec<u8>,
103 }
104
105 impl AuthenticatedPayload {
106 pub fn into_message(self) -> GiteratedMessage<NetworkedObject, NetworkedOperation> {
107 GiteratedMessage {
108 object: NetworkedObject::from_str(&self.object).unwrap(),
109 operation: self.operation,
110 payload: serde_json::from_slice(&self.payload).unwrap(),
111 }
112 }
113 }
114
115 pub trait AuthenticationSourceProvider: Debug {
116 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
117 }
118
119 pub trait AuthenticationSourceProviders: Debug {
120 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
121 }
122
123 impl<A> AuthenticationSourceProviders for A
124 where
125 A: AuthenticationSourceProvider,
126 {
127 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
128 vec![self.authenticate(payload)]
129 }
130 }
131
132 impl<A, B> AuthenticationSourceProviders for (A, B)
133 where
134 A: AuthenticationSourceProvider,
135 B: AuthenticationSourceProvider,
136 {
137 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
138 let (first, second) = self;
139
140 vec![first.authenticate(payload), second.authenticate(payload)]
141 }
142 }
143
144 #[derive(Clone, Debug)]
145 pub struct UserAuthenticator {
146 pub user: User,
147 pub token: UserAuthenticationToken,
148 }
149
150 impl AuthenticationSourceProvider for UserAuthenticator {
151 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
152 AuthenticationSource::User {
153 user: self.user.clone(),
154 token: self.token.clone(),
155 }
156 }
157 }
158
159 #[derive(Debug, Clone)]
160 pub struct InstanceAuthenticator {
161 pub instance: Instance,
162 pub private_key: String,
163 }
164
165 impl AuthenticationSourceProvider for InstanceAuthenticator {
166 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
167 let mut rng = rand::thread_rng();
168
169 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
170 let signing_key = SigningKey::<Sha256>::new(private_key);
171 let signature = signing_key.sign_with_rng(&mut rng, payload);
172
173 AuthenticationSource::Instance {
174 instance: self.instance.clone(),
175 // TODO: Actually parse signature from private key
176 signature: InstanceSignature(signature.to_bytes().into_vec()),
177 }
178 }
179 }
180
181 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
182 pub enum AuthenticationSource {
183 User {
184 user: User,
185 token: UserAuthenticationToken,
186 },
187 Instance {
188 instance: Instance,
189 signature: InstanceSignature,
190 },
191 }
192
193 #[derive(Serialize)]
194 #[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation<O>"))]
195 pub struct GiteratedMessage<O: GiteratedObject, V: GiteratedOperation<O>> {
196 #[serde(with = "string")]
197 pub object: O,
198 pub operation: String,
199 pub payload: V,
200 }
201
202 #[allow(unused)]
203 mod string {
204 use std::fmt::Display;
205 use std::str::FromStr;
206
207 use serde::{de, Deserialize, Deserializer, Serializer};
208
209 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
210 where
211 T: Display,
212 S: Serializer,
213 {
214 serializer.collect_str(value)
215 }
216
217 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
218 where
219 T: FromStr,
220 T::Err: Display,
221 D: Deserializer<'de>,
222 {
223 String::deserialize(deserializer)?
224 .parse()
225 .map_err(de::Error::custom)
226 }
227 }
228
229 impl GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
230 pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
231 &self,
232 ) -> Result<GiteratedMessage<O, V>, ()> {
233 let object = O::from_object_str(&self.object.0).map_err(|_| ())?;
234 let payload = serde_json::from_slice::<V>(&self.payload.0).map_err(|_| ())?;
235
236 Ok(GiteratedMessage {
237 object,
238 operation: self.operation.clone(),
239 payload,
240 })
241 }
242 }
243
244 impl<V: GiteratedOperation<O> + Debug, O: GiteratedObject + Debug> Debug
245 for GiteratedMessage<O, V>
246 {
247 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
248 f.debug_struct("GiteratedMessage")
249 .field("object", &self.object)
250 .field("operation", &self.operation)
251 .field("payload", &self.payload)
252 .finish()
253 }
254 }
255
256 #[derive(Debug, Clone, thiserror::Error)]
257 #[error("a remote internal error occurred")]
258 pub struct RemoteError;
259
260 #[derive(Debug, thiserror::Error)]
261 #[error("a remote internal error occurred")]
262
263 pub struct NetworkError;
264
265 #[derive(Debug)]
266 pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
267 pub source: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
268 pub message: GiteratedMessage<O, D>,
269 }
270
271 impl<O: GiteratedObject, D: GiteratedOperation<O>> Authenticated<O, D> {
272 pub fn new(message: GiteratedMessage<O, D>) -> Self {
273 Self {
274 source: vec![],
275 message,
276 }
277 }
278
279 pub fn append_authentication(
280 &mut self,
281 authentication: Arc<dyn AuthenticationSourceProviders + Send + Sync>,
282 ) {
283 self.source.push(authentication);
284 }
285
286 pub fn into_payload(mut self) -> AuthenticatedPayload {
287 let payload = serde_json::to_vec(&self.message.payload).unwrap();
288
289 AuthenticatedPayload {
290 object: self.message.object.to_string(),
291 operation: self.message.operation,
292 source: self
293 .source
294 .drain(..)
295 .flat_map(|provider| provider.as_ref().authenticate_all(&payload))
296 .collect::<Vec<_>>(),
297 payload,
298 }
299 }
300 }
301
302 #[derive(Clone, Debug)]
303 pub struct ProtocolState {
304 pub home_uri: Option<String>,
305 }
306