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

ambee/giterated

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

Fix types

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨7eb1974

⁨giterated-stack/src/lib.rs⁩ - ⁨12866⁩ 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, 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")]
118 pub struct MissingValue;
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.user.clone().ok_or(ExtractorError(MissingValue))
132 }
133 }
134
135 #[async_trait::async_trait(?Send)]
136 impl<O: GiteratedObject, D: GiteratedOperation<O> + Send + Sync> FromOperationState<O, D>
137 for AuthenticatedInstance
138 {
139 type Error = MissingValue;
140
141 async fn from_state(
142 _object: &O,
143 _operation: &D,
144 state: &StackOperationState,
145 ) -> Result<AuthenticatedInstance, ExtractorError<MissingValue>> {
146 state.instance.clone().ok_or(ExtractorError(MissingValue))
147 }
148 }
149
150 #[async_trait::async_trait(?Send)]
151 impl<
152 T: FromOperationState<O, D> + Send + Sync,
153 O: GiteratedObject + Sync,
154 D: GiteratedOperation<O> + Send + Sync,
155 > FromOperationState<O, D> for Option<T>
156 {
157 type Error = Infallible;
158
159 async fn from_state(
160 object: &O,
161 operation: &D,
162 state: &StackOperationState,
163 ) -> Result<Option<T>, ExtractorError<Infallible>> {
164 Ok(T::from_state(object, operation, state).await.ok())
165 }
166 }
167
168 #[derive(Clone)]
169 pub struct AuthorizedUser(AuthenticatedUser);
170
171 #[derive(Clone)]
172 pub struct AuthorizedInstance(AuthenticatedInstance);
173
174 #[async_trait::async_trait(?Send)]
175 pub trait AuthorizedOperation<O: GiteratedObject>: GiteratedOperation<O> {
176 type Error: Into<anyhow::Error>;
177
178 async fn authorize(
179 &self,
180 authorize_for: &O,
181 state: &StackOperationState,
182 ) -> Result<bool, ExtractorError<Self::Error>>;
183 }
184
185 #[async_trait::async_trait(?Send)]
186 impl<O: GiteratedObject + Send + Sync + Debug + 'static> AuthorizedOperation<O> for GetValue {
187 type Error = anyhow::Error;
188
189 async fn authorize(
190 &self,
191 authorize_for: &O,
192 operation_state: &StackOperationState,
193 ) -> Result<bool, ExtractorError<anyhow::Error>> {
194 Ok(operation_state
195 .runtime
196 .get_object::<O>(&authorize_for.to_string(), operation_state)
197 .await
198 .is_ok())
199 }
200 }
201
202 #[async_trait::async_trait(?Send)]
203 impl AuthorizedOperation<User> for SetSetting {
204 type Error = MissingValue;
205
206 async fn authorize(
207 &self,
208 authorize_for: &User,
209 operation_state: &StackOperationState,
210 ) -> Result<bool, ExtractorError<MissingValue>> {
211 let authenticated_user = operation_state.user.as_ref().ok_or(MissingValue)?;
212
213 Ok(authorize_for == authenticated_user.deref())
214 }
215 }
216
217 #[async_trait::async_trait(?Send)]
218 impl AuthorizedOperation<User> for GetSetting {
219 type Error = MissingValue;
220
221 async fn authorize(
222 &self,
223 authorize_for: &User,
224 operation_state: &StackOperationState,
225 ) -> Result<bool, ExtractorError<MissingValue>> {
226 let authenticated_user = operation_state.user.as_ref().ok_or(MissingValue)?;
227
228 Ok(authorize_for == authenticated_user.deref())
229 }
230 }
231
232 #[async_trait::async_trait(?Send)]
233 impl AuthorizedOperation<Repository> for SetSetting {
234 type Error = anyhow::Error;
235
236 async fn authorize(
237 &self,
238 authorize_for: &Repository,
239 operation_state: &StackOperationState,
240 ) -> Result<bool, ExtractorError<anyhow::Error>> {
241 let authenticated_user = operation_state
242 .user
243 .as_ref()
244 .ok_or_else(|| anyhow::Error::from(MissingValue))?;
245
246 let mut object = operation_state
247 .runtime
248 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
249 .await
250 .map_err(anyhow::Error::from)?;
251
252 let access_list = object
253 .get_setting::<AccessList>(operation_state)
254 .await
255 .map_err(anyhow::Error::from)?;
256
257 if access_list
258 .0
259 .iter()
260 .any(|user| user == authenticated_user.deref())
261 {
262 Ok(true)
263 } else {
264 Ok(false)
265 }
266 }
267 }
268
269 #[async_trait::async_trait(?Send)]
270 impl AuthorizedOperation<Repository> for GetSetting {
271 type Error = anyhow::Error;
272
273 async fn authorize(
274 &self,
275 authorize_for: &Repository,
276 operation_state: &StackOperationState,
277 ) -> Result<bool, ExtractorError<anyhow::Error>> {
278 let authenticated_user = operation_state
279 .user
280 .as_ref()
281 .ok_or_else(|| anyhow::Error::from(MissingValue))?;
282
283 let mut object = operation_state
284 .runtime
285 .get_object::<Repository>(&authorize_for.to_string(), operation_state)
286 .await
287 .map_err(anyhow::Error::from)?;
288
289 let access_list = object
290 .get_setting::<AccessList>(operation_state)
291 .await
292 .map_err(anyhow::Error::from)?;
293
294 if access_list
295 .0
296 .iter()
297 .any(|user| user == authenticated_user.deref())
298 {
299 Ok(true)
300 } else {
301 Ok(false)
302 }
303 }
304 }
305
306 #[async_trait::async_trait(?Send)]
307 impl AuthorizedOperation<Instance> for RegisterAccountRequest {
308 type Error = Infallible;
309
310 async fn authorize(
311 &self,
312 authorize_for: &Instance,
313 state: &StackOperationState,
314 ) -> Result<bool, ExtractorError<Infallible>> {
315 if state.our_instance == *authorize_for {
316 Ok(true)
317 } else {
318 Ok(false)
319 }
320 }
321 }
322
323 #[async_trait::async_trait(?Send)]
324 impl AuthorizedOperation<Instance> for AuthenticationTokenRequest {
325 type Error = Infallible;
326
327 async fn authorize(
328 &self,
329 authorize_for: &Instance,
330 state: &StackOperationState,
331 ) -> Result<bool, ExtractorError<Infallible>> {
332 if state.our_instance == *authorize_for {
333 Ok(true)
334 } else {
335 Ok(false)
336 }
337 }
338 }
339
340 #[async_trait::async_trait(?Send)]
341 impl AuthorizedOperation<Instance> for RepositoryCreateRequest {
342 type Error = Infallible;
343
344 async fn authorize(
345 &self,
346 authorize_for: &Instance,
347 state: &StackOperationState,
348 ) -> Result<bool, ExtractorError<Infallible>> {
349 if state.our_instance == *authorize_for {
350 Ok(true)
351 } else {
352 Ok(false)
353 }
354 }
355 }
356
357 #[async_trait::async_trait(?Send)]
358 impl<A: AuthorizedOperation<User> + Send + Sync> FromOperationState<User, A> for AuthorizedUser {
359 type Error = UnauthorizedError;
360
361 async fn from_state(
362 object: &User,
363 operation: &A,
364 state: &StackOperationState,
365 ) -> Result<AuthorizedUser, ExtractorError<UnauthorizedError>> {
366 // TODO
367 let authenticated = AuthenticatedUser::from_state(object, operation, state)
368 .await
369 .map_err(|_| ExtractorError(UnauthorizedError))?;
370
371 match operation.authorize(object, state).await {
372 Ok(authorized) => {
373 assert!(authorized);
374 }
375 Err(_err) => return Err(ExtractorError(UnauthorizedError)),
376 };
377
378 Ok(AuthorizedUser(authenticated))
379 }
380 }
381
382 #[async_trait::async_trait(?Send)]
383 impl<A: AuthorizedOperation<Instance> + Send + Sync> FromOperationState<Instance, A>
384 for AuthorizedInstance
385 {
386 type Error = UnauthorizedError;
387
388 async fn from_state(
389 object: &Instance,
390 operation: &A,
391 state: &StackOperationState,
392 ) -> Result<AuthorizedInstance, ExtractorError<UnauthorizedError>> {
393 //TODO
394 let authenticated = AuthenticatedInstance::from_state(object, operation, state)
395 .await
396 .map_err(|_| ExtractorError(UnauthorizedError))?;
397
398 match operation.authorize(object, state).await {
399 Ok(authorized) => {
400 assert!(authorized);
401 }
402 Err(_err) => return Err(ExtractorError(UnauthorizedError)),
403 };
404
405 Ok(AuthorizedInstance(authenticated))
406 }
407 }
408
409 #[derive(Clone)]
410 pub struct StackOperationState {
411 pub our_instance: Instance,
412 pub runtime: GiteratedStack<StackOperationState>,
413 pub instance: Option<AuthenticatedInstance>,
414 pub user: Option<AuthenticatedUser>,
415 }
416
417 #[derive(Clone, Debug)]
418 pub struct AuthenticatedInstance(Instance);
419
420 impl AuthenticatedInstance {
421 pub fn new(instance: Instance) -> Self {
422 AuthenticatedInstance(instance)
423 }
424 }
425
426 impl Deref for AuthenticatedInstance {
427 type Target = Instance;
428
429 fn deref(&self) -> &Self::Target {
430 &self.0
431 }
432 }
433
434 #[derive(Clone, Debug)]
435 pub struct AuthenticatedUser(User);
436
437 impl AuthenticatedUser {
438 pub fn new(user: User) -> Self {
439 AuthenticatedUser(user)
440 }
441 }
442
443 impl Deref for AuthenticatedUser {
444 type Target = User;
445
446 fn deref(&self) -> &Self::Target {
447 &self.0
448 }
449 }
450
451 #[derive(Clone, Debug, Serialize, Deserialize)]
452 #[serde(transparent)]
453 #[serde(bound(deserialize = "S: DeserializeOwned"))]
454 pub struct SettingUpdate<S: Setting + Serialize + DeserializeOwned>(pub S);
455
456 impl<O, S> GiteratedOperation<O> for SettingUpdate<S>
457 where
458 O: GiteratedObject,
459 S: Setting + Serialize + DeserializeOwned,
460 {
461 type Success = ();
462
463 type Failure = ();
464 }
465
466 pub struct OperationState<OS>(pub OS);
467
468 #[async_trait::async_trait(?Send)]
469 impl<P, OS> HandlerResolvable<P, OS> for OperationState<OS> {
470 type Error = MissingValue;
471
472 async fn from_handler_state(
473 _required_parameters: &P,
474 _operation_state: &OS,
475 ) -> Result<Self, Self::Error> {
476 todo!()
477 }
478 }
479