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

ambee/giterated

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

Unified stack refactor clean up

Clean up obsolete code and some warnings

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨356f714

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