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

ambee/giterated

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

Huge refactor to prep for moving the daemon over to the plugin architecture

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨5df753c

⁨giterated-stack/src/lib.rs⁩ - ⁨13171⁩ bytes
Raw
1 mod dynamic;
2 mod handler;
3 pub use dynamic::*;
4 pub use handler::*;
5 mod meta;
6 pub use meta::*;
7 pub mod provider;
8 mod stack;
9 pub use stack::*;
10 mod substack;
11 use serde::{de::DeserializeOwned, Deserialize, Serialize};
12 pub use stack::*;
13 pub use substack::*;
14 pub mod update;
15
16 // Temp pub use to figure out what's important
17 pub mod models {
18 pub use anyhow::Error;
19 pub use giterated_models::authenticated::*;
20 pub use giterated_models::error::{IntoInternalError, NetworkOperationError, OperationError};
21 pub use giterated_models::instance::Instance;
22 pub use giterated_models::object::GiteratedObject;
23 pub use giterated_models::operation::GiteratedOperation;
24 pub use giterated_models::user::User;
25 }
26
27 use std::{convert::Infallible, ops::Deref};
28
29 use core::fmt::Debug;
30 use giterated_models::{
31 error::{ExtractorError, UnauthorizedError},
32 instance::{
33 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
34 },
35 object::GiteratedObject,
36 object_backend::ObjectBackend,
37 operation::GiteratedOperation,
38 repository::{AccessList, Repository},
39 settings::{GetSetting, SetSetting, Setting},
40 user::User,
41 value::{GetValue, GiteratedObjectValue},
42 };
43
44 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
45 pub struct ObjectOperationPair<'a> {
46 pub object_name: &'a str,
47 pub operation_name: &'a str,
48 }
49
50 impl ObjectOperationPair<'static> {
51 #[allow(unused)]
52 pub fn from_types<O: GiteratedObject, D: GiteratedOperation<O>>() -> Self {
53 Self {
54 object_name: O::object_name(),
55 operation_name: D::operation_name(),
56 }
57 }
58 }
59
60 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
61 pub struct ObjectValuePair<'a> {
62 pub object_kind: &'a str,
63 pub value_kind: &'a str,
64 }
65
66 impl ObjectValuePair<'static> {
67 pub fn from_types<O: GiteratedObject, V: GiteratedObjectValue<Object = O>>() -> Self {
68 Self {
69 object_kind: O::object_name(),
70 value_kind: V::value_name(),
71 }
72 }
73 }
74
75 #[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
76 pub struct ObjectSettingPair<'a> {
77 pub object_kind: &'a str,
78 pub setting_name: &'a str,
79 }
80
81 impl ObjectSettingPair<'static> {
82 pub fn from_types<O: GiteratedObject, S: Setting>() -> Self {
83 Self {
84 object_kind: O::object_name(),
85 setting_name: S::name(),
86 }
87 }
88 }
89
90 #[async_trait::async_trait(?Send)]
91 pub trait FromOperationState<O: GiteratedObject, D: GiteratedOperation<O>>: Sized + Clone {
92 type Error: Into<anyhow::Error>;
93
94 async fn from_state(
95 object: &O,
96 operation: &D,
97 state: &StackOperationState,
98 ) -> Result<Self, ExtractorError<Self::Error>>;
99 }
100
101 #[async_trait::async_trait(?Send)]
102 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
103 for StackOperationState
104 {
105 type Error = Infallible;
106
107 async fn from_state(
108 _object: &O,
109 _operation: &D,
110 state: &StackOperationState,
111 ) -> Result<StackOperationState, ExtractorError<Infallible>> {
112 Ok(state.clone())
113 }
114 }
115
116 #[derive(Debug, thiserror::Error, Serialize, Deserialize)]
117 #[error("missing value {0}")]
118 pub struct MissingValue(&'static str);
119
120 #[async_trait::async_trait(?Send)]
121 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
122 for AuthenticatedUser
123 {
124 type Error = MissingValue;
125
126 async fn from_state(
127 _object: &O,
128 _operation: &D,
129 state: &StackOperationState,
130 ) -> Result<AuthenticatedUser, ExtractorError<MissingValue>> {
131 state
132 .user
133 .clone()
134 .ok_or(ExtractorError(MissingValue("AuthenticatedUser")))
135 }
136 }
137
138 #[async_trait::async_trait(?Send)]
139 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
140 for AuthenticatedInstance
141 {
142 type Error = MissingValue;
143
144 async fn from_state(
145 _object: &O,
146 _operation: &D,
147 state: &StackOperationState,
148 ) -> Result<AuthenticatedInstance, ExtractorError<MissingValue>> {
149 state
150 .instance
151 .clone()
152 .ok_or(ExtractorError(MissingValue("AuthenticatedInstance")))
153 }
154 }
155
156 #[async_trait::async_trait(?Send)]
157 impl<
158 T: FromOperationState<O, D> + Send + Sync,
159 O: GiteratedObject + Sync,
160 D: GiteratedOperation<O> + Send + Sync,
161 > FromOperationState<O, D> for Option<T>
162 {
163 type Error = Infallible;
164
165 async fn from_state(
166 object: &O,
167 operation: &D,
168 state: &StackOperationState,
169 ) -> Result<Option<T>, ExtractorError<Infallible>> {
170 Ok(T::from_state(object, operation, state).await.ok())
171 }
172 }
173
174 #[derive(Clone)]
175 pub struct AuthorizedUser(AuthenticatedUser);
176
177 #[derive(Clone)]
178 pub struct AuthorizedInstance(AuthenticatedInstance);
179
180 #[async_trait::async_trait(?Send)]
181 pub trait AuthorizedOperation<O: GiteratedObject>: GiteratedOperation<O> {
182 type Error: Into<anyhow::Error>;
183
184 async fn authorize(
185 &self,
186 authorize_for: &O,
187 state: &StackOperationState,
188 ) -> Result<bool, ExtractorError<Self::Error>>;
189 }
190
191 #[async_trait::async_trait(?Send)]
192 impl<O: GiteratedObject + Send + Sync + Debug + 'static> AuthorizedOperation<O> for GetValue {
193 type Error = anyhow::Error;
194
195 async fn authorize(
196 &self,
197 authorize_for: &O,
198 operation_state: &StackOperationState,
199 ) -> Result<bool, ExtractorError<anyhow::Error>> {
200 Ok(operation_state
201 .runtime
202 .get_object::<O>(&authorize_for.to_string(), operation_state)
203 .await
204 .is_ok())
205 }
206 }
207
208 #[async_trait::async_trait(?Send)]
209 impl AuthorizedOperation<User> for SetSetting {
210 type Error = MissingValue;
211
212 async fn authorize(
213 &self,
214 authorize_for: &User,
215 operation_state: &StackOperationState,
216 ) -> Result<bool, ExtractorError<MissingValue>> {
217 let authenticated_user = operation_state
218 .user
219 .as_ref()
220 .ok_or(MissingValue("AuthenticatedUser"))?;
221
222 Ok(authorize_for == authenticated_user.deref())
223 }
224 }
225
226 #[async_trait::async_trait(?Send)]
227 impl AuthorizedOperation<User> for GetSetting {
228 type Error = MissingValue;
229
230 async fn authorize(
231 &self,
232 authorize_for: &User,
233 operation_state: &StackOperationState,
234 ) -> Result<bool, ExtractorError<MissingValue>> {
235 let authenticated_user = operation_state
236 .user
237 .as_ref()
238 .ok_or(MissingValue("AuthenticatedUser"))?;
239
240 Ok(authorize_for == authenticated_user.deref())
241 }
242 }
243
244 #[async_trait::async_trait(?Send)]
245 impl AuthorizedOperation<Repository> for SetSetting {
246 type Error = anyhow::Error;
247
248 async fn authorize(
249 &self,
250 authorize_for: &Repository,
251 operation_state: &StackOperationState,
252 ) -> Result<bool, ExtractorError<anyhow::Error>> {
253 let authenticated_user = operation_state
254 .user
255 .as_ref()
256 .ok_or_else(|| anyhow::Error::from(MissingValue("AuthenticatedUser")))?;
257
258 let mut object = operation_state
259 .runtime
260 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
261 .await
262 .map_err(anyhow::Error::from)?;
263
264 let access_list = object
265 .get_setting::<AccessList>(operation_state)
266 .await
267 .map_err(anyhow::Error::from)?;
268
269 if access_list
270 .0
271 .iter()
272 .any(|user| user == authenticated_user.deref())
273 {
274 Ok(true)
275 } else {
276 Ok(false)
277 }
278 }
279 }
280
281 #[async_trait::async_trait(?Send)]
282 impl AuthorizedOperation<Repository> for GetSetting {
283 type Error = anyhow::Error;
284
285 async fn authorize(
286 &self,
287 authorize_for: &Repository,
288 operation_state: &StackOperationState,
289 ) -> Result<bool, ExtractorError<anyhow::Error>> {
290 let authenticated_user = operation_state
291 .user
292 .as_ref()
293 .ok_or_else(|| anyhow::Error::from(MissingValue("AuthenticatedUser")))?;
294
295 let mut object = operation_state
296 .runtime
297 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
298 .await
299 .map_err(anyhow::Error::from)?;
300
301 let access_list = object
302 .get_setting::<AccessList>(operation_state)
303 .await
304 .map_err(anyhow::Error::from)?;
305
306 if access_list
307 .0
308 .iter()
309 .any(|user| user == authenticated_user.deref())
310 {
311 Ok(true)
312 } else {
313 Ok(false)
314 }
315 }
316 }
317
318 #[async_trait::async_trait(?Send)]
319 impl AuthorizedOperation<Instance> for RegisterAccountRequest {
320 type Error = Infallible;
321
322 async fn authorize(
323 &self,
324 authorize_for: &Instance,
325 state: &StackOperationState,
326 ) -> Result<bool, ExtractorError<Infallible>> {
327 if state.our_instance == *authorize_for {
328 Ok(true)
329 } else {
330 Ok(false)
331 }
332 }
333 }
334
335 #[async_trait::async_trait(?Send)]
336 impl AuthorizedOperation<Instance> for AuthenticationTokenRequest {
337 type Error = Infallible;
338
339 async fn authorize(
340 &self,
341 authorize_for: &Instance,
342 state: &StackOperationState,
343 ) -> Result<bool, ExtractorError<Infallible>> {
344 if state.our_instance == *authorize_for {
345 Ok(true)
346 } else {
347 Ok(false)
348 }
349 }
350 }
351
352 #[async_trait::async_trait(?Send)]
353 impl AuthorizedOperation<Instance> for RepositoryCreateRequest {
354 type Error = Infallible;
355
356 async fn authorize(
357 &self,
358 authorize_for: &Instance,
359 state: &StackOperationState,
360 ) -> Result<bool, ExtractorError<Infallible>> {
361 if state.our_instance == *authorize_for {
362 Ok(true)
363 } else {
364 Ok(false)
365 }
366 }
367 }
368
369 #[async_trait::async_trait(?Send)]
370 impl<A: AuthorizedOperation<User> + Send + Sync> FromOperationState<User, A> for AuthorizedUser {
371 type Error = UnauthorizedError;
372
373 async fn from_state(
374 object: &User,
375 operation: &A,
376 state: &StackOperationState,
377 ) -> Result<AuthorizedUser, ExtractorError<UnauthorizedError>> {
378 // TODO
379 let authenticated = AuthenticatedUser::from_state(object, operation, state)
380 .await
381 .map_err(|_| ExtractorError(UnauthorizedError))?;
382
383 match operation.authorize(object, state).await {
384 Ok(authorized) => {
385 assert!(authorized);
386 }
387 Err(_err) => return Err(ExtractorError(UnauthorizedError)),
388 };
389
390 Ok(AuthorizedUser(authenticated))
391 }
392 }
393
394 #[async_trait::async_trait(?Send)]
395 impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance, A>
396 for AuthorizedInstance
397 {
398 type Error = UnauthorizedError;
399
400 async fn from_state(
401 object: &Instance,
402 operation: &A,
403 state: &StackOperationState,
404 ) -> Result<AuthorizedInstance, ExtractorError<UnauthorizedError>> {
405 //TODO
406 let authenticated = AuthenticatedInstance::from_state(object, operation, state)
407 .await
408 .map_err(|_| ExtractorError(UnauthorizedError))?;
409
410 match operation.authorize(object, state).await {
411 Ok(authorized) => {
412 assert!(authorized);
413 }
414 Err(_err) => return Err(ExtractorError(UnauthorizedError)),
415 };
416
417 Ok(AuthorizedInstance(authenticated))
418 }
419 }
420
421 #[derive(Clone)]
422 pub struct StackOperationState {
423 pub our_instance: Instance,
424 pub instance: Option<AuthenticatedInstance>,
425 pub user: Option<AuthenticatedUser>,
426 }
427
428 #[derive(Clone, Debug)]
429 pub struct AuthenticatedInstance(Instance);
430
431 impl AuthenticatedInstance {
432 pub fn new(instance: Instance) -> Self {
433 AuthenticatedInstance(instance)
434 }
435 }
436
437 impl Deref for AuthenticatedInstance {
438 type Target = Instance;
439
440 fn deref(&self) -> &Self::Target {
441 &self.0
442 }
443 }
444
445 #[derive(Clone, Debug)]
446 pub struct AuthenticatedUser(User);
447
448 impl AuthenticatedUser {
449 pub fn new(user: User) -> Self {
450 AuthenticatedUser(user)
451 }
452 }
453
454 impl Deref for AuthenticatedUser {
455 type Target = User;
456
457 fn deref(&self) -> &Self::Target {
458 &self.0
459 }
460 }
461
462 #[derive(Clone, Debug, Serialize, Deserialize)]
463 #[serde(transparent)]
464 #[serde(bound(deserialize = "S: DeserializeOwned"))]
465 pub struct SettingUpdate<S: Setting + Serialize + DeserializeOwned>(pub S);
466
467 impl<O, S> GiteratedOperation<O> for SettingUpdate<S>
468 where
469 O: GiteratedObject,
470 S: Setting + Serialize + DeserializeOwned,
471 {
472 type Success = ();
473
474 type Failure = ();
475 }
476
477 pub struct OperationState<OS>(pub OS);
478
479 #[async_trait::async_trait(?Send)]
480 impl<P, OS: Clone> HandlerResolvable<P, OS> for OperationState<OS> {
481 type Error = MissingValue;
482
483 async fn from_handler_state(
484 _required_parameters: &P,
485 operation_state: &OS,
486 ) -> Result<Self, Self::Error> {
487 Ok(Self(operation_state.clone()))
488 }
489 }
490