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

ambee/giterated

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

Add support for networked GetSetting to Unified Stack refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨da6d78e

⁨giterated-stack/src/lib.rs⁩ - ⁨20518⁩ bytes
Raw
1 mod handler;
2 pub use handler::{GiteratedStack, GiteratedStackState, *};
3 use serde_json::Value;
4
5 pub mod state;
6 pub mod update;
7
8 use std::{any::Any, future::Future, ops::Deref, pin::Pin, sync::Arc};
9
10 use core::fmt::Debug;
11 use futures_util::FutureExt;
12 use giterated_models::{
13 error::OperationError,
14 instance::{
15 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
16 },
17 object::GiteratedObject,
18 object_backend::ObjectBackend,
19 operation::GiteratedOperation,
20 repository::{AccessList, Repository},
21 settings::{GetSetting, SetSetting},
22 user::User,
23 value::GetValue,
24 };
25 use serde::{de::DeserializeOwned, Serialize};
26
27 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
28 struct ObjectOperationPair {
29 pub object_name: String,
30 pub operation_name: String,
31 }
32
33 pub struct SettingMeta {
34 pub name: String,
35 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
36 pub serialize:
37 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Value, serde_json::Error> + Send + Sync>,
38 }
39
40 pub struct ValueMeta {
41 pub name: String,
42 pub deserialize: Box<dyn Fn(&[u8]) -> Result<Box<dyn Any>, serde_json::Error> + Send + Sync>,
43 pub serialize:
44 Box<dyn Fn(Box<dyn Any + Send + Sync>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
45 pub typed_get: Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
46 pub is_get_value_typed: Box<dyn Fn(&Box<dyn Any + Send + Sync>) -> bool + Send + Sync>,
47 }
48
49 pub struct ObjectMeta {
50 pub name: String,
51 pub from_str: Box<dyn Fn(&str) -> Result<Box<dyn Any + Send + Sync>, ()> + Send + Sync>,
52 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
53 }
54
55 pub struct OperationMeta {
56 pub name: String,
57 pub object_kind: String,
58 pub deserialize:
59 Box<dyn Fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, serde_json::Error> + Send + Sync>,
60 pub any_is_same: Box<dyn Fn(&dyn Any) -> bool + Send + Sync>,
61 pub serialize_success:
62 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
63 pub serialize_error:
64 Box<dyn Fn(Box<dyn Any>) -> Result<Vec<u8>, serde_json::Error> + Send + Sync>,
65 }
66
67 #[derive(Clone, Debug, Hash, Eq, PartialEq)]
68 pub struct ObjectValuePair {
69 pub object_kind: String,
70 pub value_kind: String,
71 }
72
73 #[async_trait::async_trait(?Send)]
74 pub trait GiteratedOperationHandler<
75 L,
76 O: GiteratedObject,
77 D: GiteratedOperation<O>,
78 S: Send + Sync + Clone,
79 >
80 {
81 fn operation_name(&self) -> &str;
82 fn object_name(&self) -> &str;
83
84 async fn handle(
85 &self,
86 object: &O,
87 operation: D,
88 state: S,
89 operation_state: &StackOperationState,
90 ) -> Result<D::Success, OperationError<D::Failure>>;
91 }
92
93 #[async_trait::async_trait(?Send)]
94 impl<O, D, F, S> GiteratedOperationHandler<(), O, D, S> for F
95 where
96 F: FnMut(
97 &O,
98 D,
99 S,
100 )
101 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
102 + Send
103 + Sync
104 + Clone,
105 O: GiteratedObject + Send + Sync,
106 D: GiteratedOperation<O> + 'static,
107 <D as GiteratedOperation<O>>::Failure: Send,
108 S: Send + Sync + Clone + 'static,
109 {
110 fn operation_name(&self) -> &str {
111 D::operation_name()
112 }
113
114 fn object_name(&self) -> &str {
115 O::object_name()
116 }
117
118 async fn handle(
119 &self,
120 object: &O,
121 operation: D,
122 state: S,
123 _operation_state: &StackOperationState,
124 ) -> Result<D::Success, OperationError<D::Failure>> {
125 self.clone()(object, operation, state).await
126 }
127 }
128
129 #[async_trait::async_trait(?Send)]
130 impl<O, O1, D, F, S> GiteratedOperationHandler<(O1,), O, D, S> for F
131 where
132 F: FnMut(
133 &O,
134 D,
135 S,
136 O1,
137 )
138 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
139 + Send
140 + Sync
141 + Clone,
142 O: GiteratedObject + Send + Sync,
143 D: GiteratedOperation<O> + 'static + Send + Sync,
144 <D as GiteratedOperation<O>>::Failure: Send,
145 S: Send + Sync + Clone + 'static,
146 O1: FromOperationState<O, D>,
147 {
148 fn operation_name(&self) -> &str {
149 D::operation_name()
150 }
151
152 fn object_name(&self) -> &str {
153 O::object_name()
154 }
155
156 async fn handle(
157 &self,
158 object: &O,
159 operation: D,
160 state: S,
161 operation_state: &StackOperationState,
162 ) -> Result<D::Success, OperationError<D::Failure>> {
163 let o1 = O1::from_state(object, &operation, operation_state)
164 .await
165 .map_err(|e| OperationError::Internal(e.to_string()))?;
166 self.clone()(object, operation, state, o1).await
167 }
168 }
169
170 #[async_trait::async_trait(?Send)]
171 impl<O, O1, O2, D, F, S> GiteratedOperationHandler<(O1, O2), O, D, S> for F
172 where
173 F: FnMut(
174 &O,
175 D,
176 S,
177 O1,
178 O2,
179 )
180 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
181 + Send
182 + Sync
183 + Clone,
184 O: GiteratedObject + Send + Sync,
185 D: GiteratedOperation<O> + 'static + Send + Sync,
186 <D as GiteratedOperation<O>>::Failure: Send,
187 S: Send + Sync + Clone + 'static,
188 O1: FromOperationState<O, D>,
189 O2: FromOperationState<O, D>,
190 {
191 fn operation_name(&self) -> &str {
192 D::operation_name()
193 }
194
195 fn object_name(&self) -> &str {
196 O::object_name()
197 }
198
199 async fn handle(
200 &self,
201 object: &O,
202 operation: D,
203 state: S,
204 operation_state: &StackOperationState,
205 ) -> Result<D::Success, OperationError<D::Failure>> {
206 let o1 = O1::from_state(object, &operation, operation_state)
207 .await
208 .map_err(|e| OperationError::Internal(e.to_string()))?;
209 let o2 = O2::from_state(object, &operation, operation_state)
210 .await
211 .map_err(|e| OperationError::Internal(e.to_string()))?;
212 self.clone()(object, operation, state, o1, o2).await
213 }
214 }
215
216 #[async_trait::async_trait(?Send)]
217 impl<O, O1, O2, O3, D, F, S> GiteratedOperationHandler<(O1, O2, O3), O, D, S> for F
218 where
219 F: FnMut(
220 &O,
221 D,
222 S,
223 O1,
224 O2,
225 O3,
226 )
227 -> Pin<Box<dyn Future<Output = Result<D::Success, OperationError<D::Failure>>>>>
228 + Send
229 + Sync
230 + Clone,
231 O: GiteratedObject + Send + Sync,
232 D: GiteratedOperation<O> + 'static + Send + Sync,
233 <D as GiteratedOperation<O>>::Failure: Send,
234 S: Send + Sync + Clone + 'static,
235 O1: FromOperationState<O, D>,
236 O2: FromOperationState<O, D>,
237 O3: FromOperationState<O, D>,
238 {
239 fn operation_name(&self) -> &str {
240 D::operation_name()
241 }
242
243 fn object_name(&self) -> &str {
244 O::object_name()
245 }
246
247 async fn handle(
248 &self,
249 object: &O,
250 operation: D,
251 state: S,
252 operation_state: &StackOperationState,
253 ) -> Result<D::Success, OperationError<D::Failure>> {
254 let o1 = O1::from_state(object, &operation, operation_state)
255 .await
256 .map_err(|e| OperationError::Internal(e.to_string()))?;
257 let o2 = O2::from_state(object, &operation, operation_state)
258 .await
259 .map_err(|e| OperationError::Internal(e.to_string()))?;
260 let o3 = O3::from_state(object, &operation, operation_state)
261 .await
262 .map_err(|e| OperationError::Internal(e.to_string()))?;
263 self.clone()(object, operation, state, o1, o2, o3).await
264 }
265 }
266
267 pub struct OperationWrapper {
268 func: Box<
269 dyn Fn(
270 &(dyn Any + Send + Sync),
271 &(dyn Any + Send + Sync),
272 &(dyn Any + Send + Sync),
273 StackOperationState,
274 ) -> Pin<
275 Box<
276 dyn Future<
277 Output = Result<
278 Box<dyn Any + Send + Sync>,
279 OperationError<Box<dyn Any + Send + Sync>>,
280 >,
281 >,
282 >,
283 > + Send
284 + Sync,
285 >,
286 state: Box<dyn Any + Send + Sync>,
287 }
288
289 impl OperationWrapper {
290 pub fn new<
291 A,
292 O: GiteratedObject + Send + Sync + 'static,
293 D: GiteratedOperation<O> + 'static + Clone,
294 F: GiteratedOperationHandler<A, O, D, S> + 'static + Send + Sync + Clone,
295 S: GiteratedStackState + 'static,
296 >(
297 handler: F,
298 state: S,
299 ) -> Self
300 where
301 D::Failure: Send + Sync,
302 D::Success: Send + Sync,
303 {
304 Self {
305 func: Box::new(move |object, operation, state, operation_state| {
306 let handler = handler.clone();
307 let state = state.downcast_ref::<S>().unwrap().clone();
308 let object: &O = object.downcast_ref().unwrap();
309 let operation: &D = operation.downcast_ref().unwrap();
310 let object = object.clone();
311 let operation = operation.clone();
312 async move {
313 let result = handler
314 .handle(&object, operation, state, &operation_state)
315 .await;
316 result
317 .map(|success| Box::new(success) as _)
318 .map_err(|err| match err {
319 OperationError::Operation(err) => {
320 OperationError::Operation(Box::new(err) as _)
321 }
322 OperationError::Internal(internal) => {
323 OperationError::Internal(internal)
324 }
325 OperationError::Unhandled => OperationError::Unhandled,
326 })
327 }
328 .boxed_local()
329 }),
330 state: Box::new(state),
331 }
332 }
333
334 async fn handle(
335 &self,
336 object: &Box<dyn Any + Send + Sync>,
337 operation: &Box<dyn Any + Send + Sync>,
338 operation_state: &StackOperationState,
339 ) -> Result<Box<dyn Any + Send + Sync>, OperationError<Box<dyn Any + Send + Sync>>> {
340 (self.func)(
341 (*object).as_ref(),
342 (*operation).as_ref(),
343 self.state.as_ref(),
344 operation_state.clone(),
345 )
346 .await
347 }
348 }
349
350 #[async_trait::async_trait(?Send)]
351 pub trait FromOperationState<O: GiteratedObject, D: GiteratedOperation<O>>: Sized + Clone {
352 type Error: Serialize + DeserializeOwned;
353
354 async fn from_state(
355 object: &O,
356 operation: &D,
357 state: &StackOperationState,
358 ) -> Result<Self, OperationError<Self::Error>>;
359 }
360
361 #[async_trait::async_trait(?Send)]
362 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
363 for Arc<GiteratedStack>
364 {
365 type Error = ();
366
367 async fn from_state(
368 _object: &O,
369 _operation: &D,
370 state: &StackOperationState,
371 ) -> Result<Self, OperationError<()>> {
372 Ok(state.runtime.clone())
373 }
374 }
375
376 #[async_trait::async_trait(?Send)]
377 impl<O: GiteratedObject, D: GiteratedOperation<O>> FromOperationState<O, D>
378 for StackOperationState
379 {
380 type Error = ();
381
382 async fn from_state(
383 _object: &O,
384 _operation: &D,
385 state: &StackOperationState,
386 ) -> Result<StackOperationState, OperationError<()>> {
387 Ok(state.clone())
388 }
389 }
390
391 #[async_trait::async_trait(?Send)]
392 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
393 for AuthenticatedUser
394 {
395 type Error = ();
396
397 async fn from_state(
398 _object: &O,
399 _operation: &D,
400 state: &StackOperationState,
401 ) -> Result<AuthenticatedUser, OperationError<()>> {
402 state
403 .user
404 .clone()
405 .ok_or_else(|| OperationError::Operation(()))
406 }
407 }
408
409 #[async_trait::async_trait(?Send)]
410 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
411 for AuthenticatedInstance
412 {
413 type Error = ();
414
415 async fn from_state(
416 _object: &O,
417 _operation: &D,
418 state: &StackOperationState,
419 ) -> Result<AuthenticatedInstance, OperationError<()>> {
420 state
421 .instance
422 .clone()
423 .ok_or_else(|| OperationError::Operation(()))
424 }
425 }
426
427 #[async_trait::async_trait(?Send)]
428 impl<
429 T: FromOperationState<O, D> + Send + Sync,
430 O: GiteratedObject + Sync,
431 D: GiteratedOperation<O> + Send + Sync,
432 > FromOperationState<O, D> for Option<T>
433 {
434 type Error = ();
435
436 async fn from_state(
437 object: &O,
438 operation: &D,
439 state: &StackOperationState,
440 ) -> Result<Option<T>, OperationError<()>> {
441 Ok(T::from_state(object, operation, state).await.ok())
442 }
443 }
444
445 #[derive(Clone)]
446 pub struct AuthorizedUser(AuthenticatedUser);
447
448 #[derive(Clone)]
449 pub struct AuthorizedInstance(AuthenticatedInstance);
450
451 #[async_trait::async_trait(?Send)]
452 pub trait AuthorizedOperation<O: GiteratedObject>: GiteratedOperation<O> {
453 async fn authorize(
454 &self,
455 authorize_for: &O,
456 state: &StackOperationState,
457 ) -> Result<bool, OperationError<()>>;
458 }
459
460 #[async_trait::async_trait(?Send)]
461 impl<O: GiteratedObject + Send + Sync + Debug + 'static> AuthorizedOperation<O> for GetValue {
462 async fn authorize(
463 &self,
464 authorize_for: &O,
465 operation_state: &StackOperationState,
466 ) -> Result<bool, OperationError<()>> {
467 Ok(operation_state
468 .runtime
469 .get_object::<O>(&authorize_for.to_string(), operation_state)
470 .await
471 .is_ok())
472 }
473 }
474
475 #[async_trait::async_trait(?Send)]
476 impl AuthorizedOperation<User> for SetSetting {
477 async fn authorize(
478 &self,
479 authorize_for: &User,
480 operation_state: &StackOperationState,
481 ) -> Result<bool, OperationError<()>> {
482 let authenticated_user = operation_state
483 .user
484 .as_ref()
485 .ok_or_else(|| OperationError::Operation(()))?;
486
487 Ok(authorize_for == authenticated_user.deref())
488 }
489 }
490
491 #[async_trait::async_trait(?Send)]
492 impl AuthorizedOperation<User> for GetSetting {
493 async fn authorize(
494 &self,
495 authorize_for: &User,
496 operation_state: &StackOperationState,
497 ) -> Result<bool, OperationError<()>> {
498 let authenticated_user = operation_state
499 .user
500 .as_ref()
501 .ok_or_else(|| OperationError::Operation(()))?;
502
503 Ok(authorize_for == authenticated_user.deref())
504 }
505 }
506
507 #[async_trait::async_trait(?Send)]
508 impl AuthorizedOperation<Repository> for SetSetting {
509 async fn authorize(
510 &self,
511 authorize_for: &Repository,
512 operation_state: &StackOperationState,
513 ) -> Result<bool, OperationError<()>> {
514 let authenticated_user = operation_state
515 .user
516 .as_ref()
517 .ok_or_else(|| OperationError::Operation(()))?;
518
519 let mut object = operation_state
520 .runtime
521 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
522 .await
523 .map_err(|e| OperationError::Internal(e.to_string()))?;
524
525 let access_list = object
526 .get_setting::<AccessList>(operation_state)
527 .await
528 .map_err(|e| OperationError::Internal(e.to_string()))?;
529
530 if access_list
531 .0
532 .iter()
533 .find(|user| *user == authenticated_user.deref())
534 .is_some()
535 {
536 Ok(true)
537 } else {
538 Ok(false)
539 }
540 }
541 }
542
543 #[async_trait::async_trait(?Send)]
544 impl AuthorizedOperation<Repository> for GetSetting {
545 async fn authorize(
546 &self,
547 authorize_for: &Repository,
548 operation_state: &StackOperationState,
549 ) -> Result<bool, OperationError<()>> {
550 let authenticated_user = operation_state
551 .user
552 .as_ref()
553 .ok_or_else(|| OperationError::Operation(()))?;
554
555 let mut object = operation_state
556 .runtime
557 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
558 .await
559 .map_err(|e| OperationError::Internal(e.to_string()))?;
560
561 let access_list = object
562 .get_setting::<AccessList>(operation_state)
563 .await
564 .map_err(|e| OperationError::Internal(e.to_string()))?;
565
566 if access_list
567 .0
568 .iter()
569 .find(|user| *user == authenticated_user.deref())
570 .is_some()
571 {
572 Ok(true)
573 } else {
574 Ok(false)
575 }
576 }
577 }
578
579 #[async_trait::async_trait(?Send)]
580 impl AuthorizedOperation<Instance> for RegisterAccountRequest {
581 async fn authorize(
582 &self,
583 authorize_for: &Instance,
584 state: &StackOperationState,
585 ) -> Result<bool, OperationError<()>> {
586 if state.our_instance == *authorize_for {
587 Ok(true)
588 } else {
589 Ok(false)
590 }
591 }
592 }
593
594 #[async_trait::async_trait(?Send)]
595 impl AuthorizedOperation<Instance> for AuthenticationTokenRequest {
596 async fn authorize(
597 &self,
598 authorize_for: &Instance,
599 state: &StackOperationState,
600 ) -> Result<bool, OperationError<()>> {
601 if state.our_instance == *authorize_for {
602 Ok(true)
603 } else {
604 Ok(false)
605 }
606 }
607 }
608
609 #[async_trait::async_trait(?Send)]
610 impl AuthorizedOperation<Instance> for RepositoryCreateRequest {
611 async fn authorize(
612 &self,
613 authorize_for: &Instance,
614 state: &StackOperationState,
615 ) -> Result<bool, OperationError<()>> {
616 if state.our_instance == *authorize_for {
617 Ok(true)
618 } else {
619 Ok(false)
620 }
621 }
622 }
623
624 #[async_trait::async_trait(?Send)]
625 impl<A: AuthorizedOperation<User> + Send + Sync> FromOperationState<User, A> for AuthorizedUser {
626 type Error = ();
627
628 async fn from_state(
629 object: &User,
630 operation: &A,
631 state: &StackOperationState,
632 ) -> Result<AuthorizedUser, OperationError<()>> {
633 let authenticated = AuthenticatedUser::from_state(object, operation, state).await?;
634
635 match operation.authorize(object, state).await {
636 Ok(authorized) => {
637 assert!(authorized);
638 }
639 Err(err) => return Err(OperationError::Internal(err.to_string())),
640 };
641
642 Ok(AuthorizedUser(authenticated))
643 }
644 }
645
646 #[async_trait::async_trait(?Send)]
647 impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance, A>
648 for AuthorizedInstance
649 {
650 type Error = ();
651
652 async fn from_state(
653 object: &Instance,
654 operation: &A,
655 state: &StackOperationState,
656 ) -> Result<AuthorizedInstance, OperationError<()>> {
657 let authenticated = AuthenticatedInstance::from_state(object, operation, state).await?;
658
659 match operation.authorize(object, state).await {
660 Ok(authorized) => {
661 assert!(authorized);
662 }
663 Err(err) => return Err(OperationError::Internal(err.to_string())),
664 };
665
666 Ok(AuthorizedInstance(authenticated))
667 }
668 }
669
670 // #[async_trait::async_trait> FromOperationState for Option<T> {
671 // type Error = ();
672
673 // async fn from_state(state: &StackOperationState) -> Result<Option<T>, OperationError<()>> {
674 // Ok(T::from_state(]
675 // impl<T: FromOperationStatestate).await.ok())
676 // }
677 // }
678
679 #[derive(Clone)]
680 pub struct StackOperationState {
681 pub our_instance: Instance,
682 pub runtime: Arc<GiteratedStack>,
683 pub instance: Option<AuthenticatedInstance>,
684 pub user: Option<AuthenticatedUser>,
685 }
686
687 #[derive(Clone, Debug)]
688 pub struct AuthenticatedInstance(Instance);
689
690 impl AuthenticatedInstance {
691 pub fn new(instance: Instance) -> Self {
692 AuthenticatedInstance(instance)
693 }
694 }
695
696 impl Deref for AuthenticatedInstance {
697 type Target = Instance;
698
699 fn deref(&self) -> &Self::Target {
700 &self.0
701 }
702 }
703
704 #[derive(Clone, Debug)]
705 pub struct AuthenticatedUser(User);
706
707 impl AuthenticatedUser {
708 pub fn new(user: User) -> Self {
709 AuthenticatedUser(user)
710 }
711 }
712
713 impl Deref for AuthenticatedUser {
714 type Target = User;
715
716 fn deref(&self) -> &Self::Target {
717 &self.0
718 }
719 }
720