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

ambee/giterated

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

Unified stack refactor clean up

Clean up obsolete code and some warnings

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨356f714

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