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

ambee/giterated

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

Completely refactor project structure

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨ae8ff44

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