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

ambee/giterated

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

Fixed imports!

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨ef0e853

⁨giterated-models/src/authenticated.rs⁩ - ⁨5428⁩ 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 serde_json::Value;
12 use tracing::info;
13
14 use crate::{
15 instance::Instance,
16 message::GiteratedMessage,
17 object::{AnyObject, GiteratedObject},
18 operation::{AnyOperation, GiteratedOperation},
19 user::User,
20 };
21
22 #[derive(Debug, Serialize, Deserialize)]
23 pub struct UserTokenMetadata {
24 pub user: User,
25 pub generated_for: Instance,
26 pub exp: u64,
27 }
28
29 #[derive(Debug)]
30 pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
31 pub source: Vec<Box<dyn AuthenticationSourceProvider + Send + Sync>>,
32 pub message: GiteratedMessage<O, D>,
33 }
34
35 #[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
36 pub struct AuthenticatedPayload {
37 pub source: Vec<AuthenticationSource>,
38 pub object: String,
39 pub operation: String,
40 pub payload: Vec<u8>,
41 }
42
43 impl AuthenticatedPayload {
44 pub fn into_message(self) -> GiteratedMessage<AnyObject, AnyOperation> {
45 GiteratedMessage {
46 object: AnyObject(self.object),
47 operation: self.operation,
48 payload: AnyOperation(serde_json::from_slice::<Value>(&self.payload).unwrap()),
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.payload).unwrap();
107
108 AuthenticatedPayload {
109 object: self.message.object.to_string(),
110 operation: self.message.operation,
111 source: self
112 .source
113 .drain(..)
114 .map(|provider| provider.as_ref().authenticate(&payload))
115 .collect::<Vec<_>>(),
116 payload,
117 }
118 }
119 }
120
121 mod verified {}
122
123 #[derive(Clone, Debug)]
124 pub struct UserAuthenticator {
125 pub user: User,
126 pub token: UserAuthenticationToken,
127 }
128
129 impl AuthenticationSourceProvider for UserAuthenticator {
130 fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
131 AuthenticationSource::User {
132 user: self.user.clone(),
133 token: self.token.clone(),
134 }
135 }
136 }
137
138 #[derive(Debug, Clone)]
139 pub struct InstanceAuthenticator {
140 pub instance: Instance,
141 pub private_key: String,
142 }
143
144 impl AuthenticationSourceProvider for InstanceAuthenticator {
145 fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
146 let mut rng = rand::thread_rng();
147
148 let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
149 let signing_key = SigningKey::<Sha256>::new(private_key);
150 let signature = signing_key.sign_with_rng(&mut rng, payload);
151
152 AuthenticationSource::Instance {
153 instance: self.instance.clone(),
154 // TODO: Actually parse signature from private key
155 signature: InstanceSignature(signature.to_bytes().into_vec()),
156 }
157 }
158 }
159
160 #[repr(transparent)]
161 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
162 pub struct UserAuthenticationToken(String);
163
164 impl From<String> for UserAuthenticationToken {
165 fn from(value: String) -> Self {
166 Self(value)
167 }
168 }
169
170 impl ToString for UserAuthenticationToken {
171 fn to_string(&self) -> String {
172 self.0.clone()
173 }
174 }
175
176 impl AsRef<str> for UserAuthenticationToken {
177 fn as_ref(&self) -> &str {
178 &self.0
179 }
180 }
181
182 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
183 pub struct InstanceSignature(Vec<u8>);
184
185 impl AsRef<[u8]> for InstanceSignature {
186 fn as_ref(&self) -> &[u8] {
187 &self.0
188 }
189 }
190
191 #[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
192 pub enum AuthenticationSource {
193 User {
194 user: User,
195 token: UserAuthenticationToken,
196 },
197 Instance {
198 instance: Instance,
199 signature: InstanceSignature,
200 },
201 }
202