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

ambee/giterated

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

Unified stack `GetValue` implementation

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨325f5af

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