1 |
use std::{ops::Deref, str::FromStr, sync::Arc};
|
2 |
|
3 |
use giterated_models::{
|
4 |
authenticated::{InstanceSignature, UserAuthenticationToken},
|
5 |
instance::Instance,
|
6 |
object::GiteratedObject,
|
7 |
operation::GiteratedOperation,
|
8 |
user::User,
|
9 |
};
|
10 |
use handlers::{NetworkedObject, NetworkedOperation};
|
11 |
use object::NetworkAnyObject;
|
12 |
use operations::NetworkAnyOperation;
|
13 |
use rsa::{
|
14 |
pkcs1::DecodeRsaPrivateKey,
|
15 |
pss::SigningKey,
|
16 |
sha2::Sha256,
|
17 |
signature::{RandomizedSigner, SignatureEncoding},
|
18 |
RsaPrivateKey,
|
19 |
};
|
20 |
use serde::{Deserialize, Serialize};
|
21 |
use std::fmt::Debug;
|
22 |
|
23 |
pub mod handlers;
|
24 |
pub mod object;
|
25 |
pub mod operations;
|
26 |
|
27 |
#[macro_use]
|
28 |
extern crate tracing;
|
29 |
|
30 |
#[derive(Clone)]
|
31 |
pub struct StackOperationState {
|
32 |
pub our_instance: Instance,
|
33 |
pub instance: Option<AuthenticatedInstance>,
|
34 |
pub user: Option<AuthenticatedUser>,
|
35 |
}
|
36 |
|
37 |
#[derive(Clone, Debug)]
|
38 |
pub struct AuthenticatedInstance(Instance);
|
39 |
|
40 |
impl AuthenticatedInstance {
|
41 |
pub fn new(instance: Instance) -> Self {
|
42 |
AuthenticatedInstance(instance)
|
43 |
}
|
44 |
}
|
45 |
|
46 |
impl Deref for AuthenticatedInstance {
|
47 |
type Target = Instance;
|
48 |
|
49 |
fn deref(&self) -> &Self::Target {
|
50 |
&self.0
|
51 |
}
|
52 |
}
|
53 |
|
54 |
#[derive(Clone, Debug)]
|
55 |
pub struct AuthenticatedUser(User);
|
56 |
|
57 |
impl AuthenticatedUser {
|
58 |
pub fn new(user: User) -> Self {
|
59 |
AuthenticatedUser(user)
|
60 |
}
|
61 |
}
|
62 |
|
63 |
impl Deref for AuthenticatedUser {
|
64 |
type Target = User;
|
65 |
|
66 |
fn deref(&self) -> &Self::Target {
|
67 |
&self.0
|
68 |
}
|
69 |
}
|
70 |
|
71 |
#[derive(Clone)]
|
72 |
pub struct NetworkOperationState {
|
73 |
authentication: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
|
74 |
}
|
75 |
|
76 |
impl NetworkOperationState {
|
77 |
pub fn new() -> Self {
|
78 |
Self {
|
79 |
authentication: vec![],
|
80 |
}
|
81 |
}
|
82 |
|
83 |
pub fn authenticate(
|
84 |
&mut self,
|
85 |
provider: impl AuthenticationSourceProviders + Send + Sync + 'static,
|
86 |
) {
|
87 |
self.authentication.push(Arc::new(provider))
|
88 |
}
|
89 |
}
|
90 |
|
91 |
#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
92 |
pub struct AuthenticatedPayload {
|
93 |
pub source: Vec<AuthenticationSource>,
|
94 |
pub object: String,
|
95 |
pub operation: String,
|
96 |
pub payload: Vec<u8>,
|
97 |
}
|
98 |
|
99 |
impl AuthenticatedPayload {
|
100 |
pub fn into_message(self) -> GiteratedMessage<NetworkedObject, NetworkedOperation> {
|
101 |
GiteratedMessage {
|
102 |
object: NetworkedObject::from_str(&self.object).unwrap(),
|
103 |
operation: self.operation,
|
104 |
payload: serde_json::from_slice(&self.payload).unwrap(),
|
105 |
}
|
106 |
}
|
107 |
}
|
108 |
|
109 |
pub trait AuthenticationSourceProvider: Debug {
|
110 |
fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource;
|
111 |
}
|
112 |
|
113 |
pub trait AuthenticationSourceProviders: Debug {
|
114 |
fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource>;
|
115 |
}
|
116 |
|
117 |
impl<A> AuthenticationSourceProviders for A
|
118 |
where
|
119 |
A: AuthenticationSourceProvider,
|
120 |
{
|
121 |
fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
|
122 |
vec![self.authenticate(payload)]
|
123 |
}
|
124 |
}
|
125 |
|
126 |
impl<A, B> AuthenticationSourceProviders for (A, B)
|
127 |
where
|
128 |
A: AuthenticationSourceProvider,
|
129 |
B: AuthenticationSourceProvider,
|
130 |
{
|
131 |
fn authenticate_all(&self, payload: &Vec<u8>) -> Vec<AuthenticationSource> {
|
132 |
let (first, second) = self;
|
133 |
|
134 |
vec![first.authenticate(payload), second.authenticate(payload)]
|
135 |
}
|
136 |
}
|
137 |
|
138 |
#[derive(Clone, Debug)]
|
139 |
pub struct UserAuthenticator {
|
140 |
pub user: User,
|
141 |
pub token: UserAuthenticationToken,
|
142 |
}
|
143 |
|
144 |
impl AuthenticationSourceProvider for UserAuthenticator {
|
145 |
fn authenticate(&self, _payload: &Vec<u8>) -> AuthenticationSource {
|
146 |
AuthenticationSource::User {
|
147 |
user: self.user.clone(),
|
148 |
token: self.token.clone(),
|
149 |
}
|
150 |
}
|
151 |
}
|
152 |
|
153 |
#[derive(Debug, Clone)]
|
154 |
pub struct InstanceAuthenticator {
|
155 |
pub instance: Instance,
|
156 |
pub private_key: String,
|
157 |
}
|
158 |
|
159 |
impl AuthenticationSourceProvider for InstanceAuthenticator {
|
160 |
fn authenticate(&self, payload: &Vec<u8>) -> AuthenticationSource {
|
161 |
let mut rng = rand::thread_rng();
|
162 |
|
163 |
let private_key = RsaPrivateKey::from_pkcs1_pem(&self.private_key).unwrap();
|
164 |
let signing_key = SigningKey::<Sha256>::new(private_key);
|
165 |
let signature = signing_key.sign_with_rng(&mut rng, payload);
|
166 |
|
167 |
AuthenticationSource::Instance {
|
168 |
instance: self.instance.clone(),
|
169 |
|
170 |
signature: InstanceSignature(signature.to_bytes().into_vec()),
|
171 |
}
|
172 |
}
|
173 |
}
|
174 |
|
175 |
#[derive(Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
|
176 |
pub enum AuthenticationSource {
|
177 |
User {
|
178 |
user: User,
|
179 |
token: UserAuthenticationToken,
|
180 |
},
|
181 |
Instance {
|
182 |
instance: Instance,
|
183 |
signature: InstanceSignature,
|
184 |
},
|
185 |
}
|
186 |
|
187 |
#[derive(Serialize)]
|
188 |
#[serde(bound(deserialize = "O: GiteratedObject, V: GiteratedOperation<O>"))]
|
189 |
pub struct GiteratedMessage<O: GiteratedObject, V: GiteratedOperation<O>> {
|
190 |
#[serde(with = "string")]
|
191 |
pub object: O,
|
192 |
pub operation: String,
|
193 |
pub payload: V,
|
194 |
}
|
195 |
|
196 |
#[allow(unused)]
|
197 |
mod string {
|
198 |
use std::fmt::Display;
|
199 |
use std::str::FromStr;
|
200 |
|
201 |
use serde::{de, Deserialize, Deserializer, Serializer};
|
202 |
|
203 |
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
|
204 |
where
|
205 |
T: Display,
|
206 |
S: Serializer,
|
207 |
{
|
208 |
serializer.collect_str(value)
|
209 |
}
|
210 |
|
211 |
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
212 |
where
|
213 |
T: FromStr,
|
214 |
T::Err: Display,
|
215 |
D: Deserializer<'de>,
|
216 |
{
|
217 |
String::deserialize(deserializer)?
|
218 |
.parse()
|
219 |
.map_err(de::Error::custom)
|
220 |
}
|
221 |
}
|
222 |
|
223 |
impl GiteratedMessage<NetworkAnyObject, NetworkAnyOperation> {
|
224 |
pub fn try_into<O: GiteratedObject, V: GiteratedOperation<O>>(
|
225 |
&self,
|
226 |
) -> Result<GiteratedMessage<O, V>, ()> {
|
227 |
let object = O::from_object_str(&self.object.0).map_err(|_| ())?;
|
228 |
let payload = serde_json::from_slice::<V>(&self.payload.0).map_err(|_| ())?;
|
229 |
|
230 |
Ok(GiteratedMessage {
|
231 |
object,
|
232 |
operation: self.operation.clone(),
|
233 |
payload,
|
234 |
})
|
235 |
}
|
236 |
}
|
237 |
|
238 |
impl<V: GiteratedOperation<O> + Debug, O: GiteratedObject + Debug> Debug
|
239 |
for GiteratedMessage<O, V>
|
240 |
{
|
241 |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
242 |
f.debug_struct("GiteratedMessage")
|
243 |
.field("object", &self.object)
|
244 |
.field("operation", &self.operation)
|
245 |
.field("payload", &self.payload)
|
246 |
.finish()
|
247 |
}
|
248 |
}
|
249 |
|
250 |
#[derive(Debug, Clone, thiserror::Error)]
|
251 |
#[error("a remote internal error occurred")]
|
252 |
pub struct RemoteError;
|
253 |
|
254 |
#[derive(Debug, thiserror::Error)]
|
255 |
#[error("a remote internal error occurred")]
|
256 |
|
257 |
pub struct NetworkError;
|
258 |
|
259 |
#[derive(Debug)]
|
260 |
pub struct Authenticated<O: GiteratedObject, D: GiteratedOperation<O>> {
|
261 |
pub source: Vec<Arc<dyn AuthenticationSourceProviders + Send + Sync>>,
|
262 |
pub message: GiteratedMessage<O, D>,
|
263 |
}
|
264 |
|
265 |
impl<O: GiteratedObject, D: GiteratedOperation<O>> Authenticated<O, D> {
|
266 |
pub fn new(message: GiteratedMessage<O, D>) -> Self {
|
267 |
Self {
|
268 |
source: vec![],
|
269 |
message,
|
270 |
}
|
271 |
}
|
272 |
|
273 |
pub fn append_authentication(
|
274 |
&mut self,
|
275 |
authentication: Arc<dyn AuthenticationSourceProviders + Send + Sync>,
|
276 |
) {
|
277 |
self.source.push(authentication);
|
278 |
}
|
279 |
|
280 |
pub fn into_payload(mut self) -> AuthenticatedPayload {
|
281 |
let payload = serde_json::to_vec(&self.message.payload).unwrap();
|
282 |
|
283 |
AuthenticatedPayload {
|
284 |
object: self.message.object.to_string(),
|
285 |
operation: self.message.operation,
|
286 |
source: self
|
287 |
.source
|
288 |
.drain(..)
|
289 |
.map(|provider| provider.as_ref().authenticate_all(&payload))
|
290 |
.flatten()
|
291 |
.collect::<Vec<_>>(),
|
292 |
payload,
|
293 |
}
|
294 |
}
|
295 |
}
|
296 |
|
297 |
#[derive(Clone, Debug)]
|
298 |
pub struct ProtocolState {
|
299 |
pub home_uri: Option<String>,
|
300 |
}
|
301 |
|