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

ambee/giterated

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

Re-expose Operation State in generics.

This is the worst code I have ever written. I hate the way this changes everything. ugh.

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90db3e2

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