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

ambee/giterated

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

Begin new protocol refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨26651b1

⁨giterated-models/src/model/authenticated.rs⁩ - ⁨5464⁩ bytes
Raw
1 use std::fmt::Debug;
2
3 use rsa::{
4 pkcs1::DecodeRsaPrivateKey,
5 pss::SigningKey,
6 sha2::Sha256,
7 signature::{RandomizedSigner, SignatureEncoding},
8 RsaPrivateKey,
9 };
10 use serde::{Deserialize, Serialize};
11 use tracing::info;
12
13 use crate::operation::{GiteratedMessage, GiteratedObject, GiteratedOperation};
14
15 use super::{instance::Instance, user::User, MessageTarget};
16
17 #[derive(Debug, Serialize, Deserialize)]
18 pub struct UserTokenMetadata {
19 pub user: User,
20 pub generated_for: Instance,
21 pub exp: u64,
22 }
23
24 #[derive(Debug)]
25 pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
26 pub source: Vec<Box<dyn AuthenticationSourceProvider + Send + Sync>>,
27 pub message: GiteratedMessage<O, D>,
28 }
29
30 #[derive(Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
31 pub struct AuthenticatedPayload {
32 pub source: Vec<AuthenticationSource>,
33 pub payload: Vec<u8>,
34 }
35
36 // impl<T: Serialize> From<Authenticated<T>> for AuthenticatedPayload {
37 // fn from(mut value: Authenticated<T>) -> Self {
38 // let payload = bincode::serialize(&value.message).unwrap();
39
40 // AuthenticatedPayload {
41 // target_instance: value.target_instance,
42 // source: value
43 // .source
44 // .drain(..)
45 // .map(|provider| provider.as_ref().authenticate(&payload))
46 // .collect::<Vec<_>>(),
47 // message_type: value.message_type,
48 // payload,
49 // }
50 // }
51 // }
52
53 pub trait AuthenticationSourceProvider: Debug {
54 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
55 }
56
57 pub trait AuthenticationSourceProviders: Debug {
58 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
59 }
60
61 impl<A> AuthenticationSourceProviders for A
62 where
63 A: AuthenticationSourceProvider,
64 {
65 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
66 vec![self.authenticate(payload)]
67 }
68 }
69
70 impl<A, B> AuthenticationSourceProviders for (A, B)
71 where
72 A: AuthenticationSourceProvider,
73 B: AuthenticationSourceProvider,
74 {
75 fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
76 let (first, second) = self;
77
78 vec![first.authenticate(payload), second.authenticate(payload)]
79 }
80 }
81
82 impl<O: GiteratedObject, D: GiteratedOperation<O>> Authenticated<O, D> {
83 pub fn new(message: GiteratedMessage<O, D>) -> Self {
84 Self {
85 source: vec![],
86 message,
87 }
88 }
89
90 pub fn append_authentication<P: AuthenticationSourceProvider + 'static + Send + Sync>(
91 &mut self,
92 authentication: P,
93 ) {
94 let message_payload = serde_json::to_vec(&self.message).unwrap();
95
96 info!(
97 "Verifying payload: {}",
98 std::str::from_utf8(&message_payload).unwrap()
99 );
100
101 self.source
102 .push(Box::new(authentication) as Box<dyn AuthenticationSourceProvider + Send + Sync>);
103 }
104
105 pub fn into_payload(mut self) -> AuthenticatedPayload {
106 let payload = bincode::serialize(&self.message).unwrap();
107
108 AuthenticatedPayload {
109 source: self
110 .source
111 .drain(..)
112 .map(|provider| provider.as_ref().authenticate(&payload))
113 .collect::<Vec<_>>(),
114 payload,
115 }
116 }
117 }
118
119 mod verified {}
120
121 #[derive(Clone, Debug)]
122 pub struct UserAuthenticator {
123 pub user: User,
124 pub token: UserAuthenticationToken,
125 }
126
127 impl AuthenticationSourceProvider for UserAuthenticator {
128 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
129 AuthenticationSource::User {
130 user: self.user.clone(),
131 token: self.token.clone(),
132 }
133 }
134 }
135
136 #[derive(Debug, Clone)]
137 pub struct InstanceAuthenticator {
138 pub instance: Instance,
139 pub private_key: String,
140 }
141
142 impl AuthenticationSourceProvider for InstanceAuthenticator {
143 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
144 let mut rng = rand::thread_rng();
145
146 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
147 let signing_key = SigningKey::<Sha256>::new(private_key);
148 let signature = signing_key.sign_with_rng(&mut rng, payload);
149
150 AuthenticationSource::Instance {
151 instance: self.instance.clone(),
152 // TODO: Actually parse signature from private key
153 signature: InstanceSignature(signature.to_bytes().into_vec()),
154 }
155 }
156 }
157
158 #[repr(transparent)]
159 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
160 pub struct UserAuthenticationToken(String);
161
162 impl From<String> for UserAuthenticationToken {
163 fn from(value: String) -> Self {
164 Self(value)
165 }
166 }
167
168 impl ToString for UserAuthenticationToken {
169 fn to_string(&self) -> String {
170 self.0.clone()
171 }
172 }
173
174 impl AsRef<str> for UserAuthenticationToken {
175 fn as_ref(&self) -> &str {
176 &self.0
177 }
178 }
179
180 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
181 pub struct InstanceSignature(Vec<u8>);
182
183 impl AsRef<[u8]> for InstanceSignature {
184 fn as_ref(&self) -> &[u8] {
185 &self.0
186 }
187 }
188
189 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
190 pub enum AuthenticationSource {
191 User {
192 user: User,
193 token: UserAuthenticationToken,
194 },
195 Instance {
196 instance: Instance,
197 signature: InstanceSignature,
198 },
199 }
200