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

ambee/giterated

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

`giterated_cache` initial implementation

# Giterated Stack - Added the ability for dynamic substack handlers to exist for operations relevant to caching. - Added type metadata to the dynamic types. # Giterated Cache - Created - Implemented caching and fetching from cache. Hell fucking yes!!!! It works so good. Are you snooping in the commit logs because you're curious about the history of giterated? Cool that it got so big... tell me I say hi :)

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨86afeef

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