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

ambee/giterated

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

Fix networked setting request

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨4b5330d

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨21702⁩ bytes
Raw
1 use std::{error::Error, sync::Arc};
2
3 use futures_util::{future::LocalBoxFuture, FutureExt};
4 use giterated_models::{
5 authenticated::UserAuthenticationToken,
6 error::{GetValueError, InstanceError, OperationError, RepositoryError, UserError},
7 instance::{
8 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
9 },
10 object_backend::ObjectBackend,
11 repository::{
12 Commit, DefaultBranch, Description, LatestCommit, Repository, RepositoryBranch,
13 RepositoryBranchesRequest, RepositoryCommitBeforeRequest, RepositoryCommitFromIdRequest,
14 RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile,
15 RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest,
16 RepositoryInfoRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics,
17 RepositoryStatisticsRequest, RepositorySummary, RepositoryView, Visibility,
18 },
19 settings::{GetSetting, GetSettingError},
20 user::{Bio, DisplayName, User, UserRepositoriesRequest},
21 value::{AnyValue, GetValueTyped},
22 };
23 use giterated_stack::{AuthenticatedUser, AuthorizedInstance, GiteratedStack, StackOperationState};
24 use serde_json::Value;
25
26 use super::DatabaseBackend;
27
28 pub fn user_get_repositories(
29 object: &User,
30 _operation: UserRepositoriesRequest,
31 state: DatabaseBackend,
32 _operation_state: StackOperationState,
33 requester: Option<AuthenticatedUser>,
34 ) -> LocalBoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
35 let object = object.clone();
36
37 async move {
38 let mut user_backend = state.user_backend.lock().await;
39 let repositories_response = user_backend
40 .repositories_for_user(&requester, &object)
41 .await
42 .map_err(|e| OperationError::Internal(e.to_string()))?;
43 drop(user_backend);
44 let mut repositories_backend = state.repository_backend.lock().await;
45
46 let mut repositories = vec![];
47
48 for repository in repositories_response {
49 if repositories_backend
50 .exists(&requester, &repository.repository)
51 .await
52 .map_err(|e| OperationError::Internal(e.to_string()))?
53 {
54 repositories.push(repository);
55 }
56 }
57
58 Ok(repositories)
59 }
60 .boxed_local()
61 }
62
63 pub fn user_get_value(
64 object: &User,
65 operation: GetValueTyped<AnyValue<User>>,
66 state: DatabaseBackend,
67 ) -> LocalBoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
68 let object = object.clone();
69
70 async move {
71 let mut user_backend = state.user_backend.lock().await;
72 let value = user_backend
73 .get_value(&object, &operation.value_name)
74 .await
75 .map_err(|e| OperationError::Internal(e.to_string()))?;
76
77 Ok(value)
78 }
79 .boxed_local()
80 }
81
82 pub fn user_get_setting(
83 object: &User,
84 operation: GetSetting,
85 state: DatabaseBackend,
86 ) -> LocalBoxFuture<'static, Result<Value, OperationError<GetSettingError>>> {
87 let object = object.clone();
88
89 async move {
90 let mut user_backend = state.user_backend.lock().await;
91 let value = user_backend
92 .get_setting(&object, &operation.setting_name)
93 .await
94 .map_err(|e| OperationError::Internal(e.to_string()))?;
95
96 Ok(value.0)
97 }
98 .boxed_local()
99 }
100
101 pub fn repository_info(
102 object: &Repository,
103 operation: RepositoryInfoRequest,
104 state: DatabaseBackend,
105 operation_state: StackOperationState,
106 backend: Arc<GiteratedStack>,
107 requester: Option<AuthenticatedUser>,
108 ) -> LocalBoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
109 let object = object.clone();
110
111 async move {
112 let mut object = backend
113 .get_object::<Repository>(&object.to_string(), &operation_state)
114 .await
115 .unwrap();
116 let mut repository_backend = state.repository_backend.lock().await;
117 let tree = repository_backend
118 .repository_file_inspect(
119 &requester,
120 object.object(),
121 &RepositoryFileInspectRequest {
122 extra_metadata: operation.extra_metadata,
123 path: operation.path,
124 rev: operation.rev.clone(),
125 },
126 )
127 .await
128 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
129
130 let statistics = repository_backend
131 .repository_get_statistics(
132 &requester,
133 object.object(),
134 &RepositoryStatisticsRequest {
135 rev: operation.rev.clone(),
136 },
137 )
138 .await
139 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
140 drop(repository_backend);
141
142 let info = RepositoryView {
143 name: object.object().name.clone(),
144 owner: object.object().owner.clone(),
145 description: object.get::<Description>(&operation_state).await.ok(),
146 visibility: object
147 .get::<Visibility>(&operation_state)
148 .await
149 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
150 default_branch: object
151 .get::<DefaultBranch>(&operation_state)
152 .await
153 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
154 // TODO: Can't be a simple get function, this needs to be returned alongside the tree as this differs depending on the rev and path.
155 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
156 stats: statistics,
157 tree_rev: operation.rev,
158 tree,
159 };
160
161 Ok(info)
162 }
163 .boxed_local()
164 }
165
166 pub fn repository_get_statistics(
167 object: &Repository,
168 operation: RepositoryStatisticsRequest,
169 state: DatabaseBackend,
170 operation_state: StackOperationState,
171 backend: Arc<GiteratedStack>,
172 requester: Option<AuthenticatedUser>,
173 ) -> LocalBoxFuture<'static, Result<RepositoryStatistics, OperationError<RepositoryError>>> {
174 let object = object.clone();
175
176 async move {
177 let object = backend
178 .get_object::<Repository>(&object.to_string(), &operation_state)
179 .await
180 .unwrap();
181
182 let mut repository_backend = state.repository_backend.lock().await;
183 let statistics = repository_backend
184 .repository_get_statistics(
185 &requester,
186 object.object(),
187 &RepositoryStatisticsRequest { rev: operation.rev },
188 )
189 .await
190 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
191 drop(repository_backend);
192
193 Ok(statistics)
194 }
195 .boxed_local()
196 }
197
198 pub fn repository_get_branches(
199 object: &Repository,
200 operation: RepositoryBranchesRequest,
201 state: DatabaseBackend,
202 operation_state: StackOperationState,
203 backend: Arc<GiteratedStack>,
204 requester: Option<AuthenticatedUser>,
205 ) -> LocalBoxFuture<'static, Result<Vec<RepositoryBranch>, OperationError<RepositoryError>>> {
206 let object = object.clone();
207
208 async move {
209 let object = backend
210 .get_object::<Repository>(&object.to_string(), &operation_state)
211 .await
212 .unwrap();
213
214 let mut repository_backend = state.repository_backend.lock().await;
215 let branches = repository_backend
216 .repository_get_branches(&requester, object.object(), &operation)
217 .await
218 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
219 drop(repository_backend);
220
221 Ok(branches)
222 }
223 .boxed_local()
224 }
225
226 pub fn repository_file_from_id(
227 object: &Repository,
228 operation: RepositoryFileFromIdRequest,
229 state: DatabaseBackend,
230 operation_state: StackOperationState,
231 backend: Arc<GiteratedStack>,
232
233 requester: Option<AuthenticatedUser>,
234 ) -> LocalBoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
235 let object = object.clone();
236
237 async move {
238 let object = backend
239 .get_object::<Repository>(&object.to_string(), &operation_state)
240 .await
241 .unwrap();
242
243 let mut repository_backend = state.repository_backend.lock().await;
244 let file = repository_backend
245 .repository_file_from_id(
246 &requester,
247 object.object(),
248 &RepositoryFileFromIdRequest(operation.0),
249 )
250 .await
251 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
252 drop(repository_backend);
253
254 Ok(file)
255 }
256 .boxed_local()
257 }
258
259 pub fn repository_file_from_path(
260 object: &Repository,
261 operation: RepositoryFileFromPathRequest,
262 state: DatabaseBackend,
263 operation_state: StackOperationState,
264 backend: Arc<GiteratedStack>,
265 requester: Option<AuthenticatedUser>,
266 ) -> LocalBoxFuture<'static, Result<(RepositoryFile, String), OperationError<RepositoryError>>> {
267 let object = object.clone();
268
269 async move {
270 let object = backend
271 .get_object::<Repository>(&object.to_string(), &operation_state)
272 .await
273 .unwrap();
274
275 let mut repository_backend = state.repository_backend.lock().await;
276 let file = repository_backend
277 .repository_file_from_path(
278 &requester,
279 object.object(),
280 &RepositoryFileFromPathRequest {
281 rev: operation.rev,
282 path: operation.path,
283 },
284 )
285 .await
286 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
287 drop(repository_backend);
288
289 Ok(file)
290 }
291 .boxed_local()
292 }
293
294 pub fn repository_last_commit_of_file(
295 object: &Repository,
296 operation: RepositoryLastCommitOfFileRequest,
297 state: DatabaseBackend,
298 operation_state: StackOperationState,
299 backend: Arc<GiteratedStack>,
300 requester: Option<AuthenticatedUser>,
301 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
302 let object = object.clone();
303
304 async move {
305 let object = backend
306 .get_object::<Repository>(&object.to_string(), &operation_state)
307 .await
308 .unwrap();
309
310 let mut repository_backend = state.repository_backend.lock().await;
311 let commit = repository_backend
312 .repository_last_commit_of_file(
313 &requester,
314 object.object(),
315 &RepositoryLastCommitOfFileRequest {
316 start_commit: operation.start_commit,
317 path: operation.path,
318 },
319 )
320 .await
321 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
322 drop(repository_backend);
323
324 Ok(commit)
325 }
326 .boxed_local()
327 }
328
329 pub fn repository_commit_by_id(
330 object: &Repository,
331 operation: RepositoryCommitFromIdRequest,
332 state: DatabaseBackend,
333 operation_state: StackOperationState,
334 backend: Arc<GiteratedStack>,
335 requester: Option<AuthenticatedUser>,
336 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
337 let object = object.clone();
338
339 async move {
340 let object = backend
341 .get_object::<Repository>(&object.to_string(), &operation_state)
342 .await
343 .unwrap();
344
345 let mut repository_backend = state.repository_backend.lock().await;
346 let commit = repository_backend
347 .repository_commit_from_id(
348 &requester,
349 object.object(),
350 &RepositoryCommitFromIdRequest(operation.0),
351 )
352 .await
353 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
354 drop(repository_backend);
355
356 Ok(commit)
357 }
358 .boxed_local()
359 }
360
361 pub fn repository_diff(
362 object: &Repository,
363 operation: RepositoryDiffRequest,
364 state: DatabaseBackend,
365 operation_state: StackOperationState,
366 backend: Arc<GiteratedStack>,
367 requester: Option<AuthenticatedUser>,
368 ) -> LocalBoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
369 let object = object.clone();
370
371 async move {
372 let object = backend
373 .get_object::<Repository>(&object.to_string(), &operation_state)
374 .await
375 .unwrap();
376
377 let mut repository_backend = state.repository_backend.lock().await;
378 let diff = repository_backend
379 .repository_diff(&requester, object.object(), &operation)
380 .await
381 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
382 drop(repository_backend);
383
384 Ok(diff)
385 }
386 .boxed_local()
387 }
388
389 pub fn repository_diff_patch(
390 object: &Repository,
391 operation: RepositoryDiffPatchRequest,
392 state: DatabaseBackend,
393 operation_state: StackOperationState,
394 backend: Arc<GiteratedStack>,
395 requester: Option<AuthenticatedUser>,
396 ) -> LocalBoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
397 let object = object.clone();
398
399 async move {
400 let object = backend
401 .get_object::<Repository>(&object.to_string(), &operation_state)
402 .await
403 .unwrap();
404
405 let mut repository_backend = state.repository_backend.lock().await;
406 let patch = repository_backend
407 .repository_diff_patch(&requester, object.object(), &operation)
408 .await
409 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
410 drop(repository_backend);
411
412 Ok(patch)
413 }
414 .boxed_local()
415 }
416
417 pub fn repository_commit_before(
418 object: &Repository,
419 operation: RepositoryCommitBeforeRequest,
420 state: DatabaseBackend,
421 operation_state: StackOperationState,
422 backend: Arc<GiteratedStack>,
423 requester: Option<AuthenticatedUser>,
424 ) -> LocalBoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
425 let object = object.clone();
426
427 async move {
428 let object = backend
429 .get_object::<Repository>(&object.to_string(), &operation_state)
430 .await
431 .unwrap();
432
433 let mut repository_backend = state.repository_backend.lock().await;
434 let file = repository_backend
435 .repository_commit_before(&requester, object.object(), &operation)
436 .await
437 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
438 drop(repository_backend);
439
440 Ok(file)
441 }
442 .boxed_local()
443 }
444
445 pub fn repository_get_value(
446 object: &Repository,
447 operation: GetValueTyped<AnyValue<Repository>>,
448 state: DatabaseBackend,
449 ) -> LocalBoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
450 let object = object.clone();
451
452 async move {
453 let mut repository_backend = state.repository_backend.lock().await;
454 let value = repository_backend
455 .get_value(&object, &operation.value_name)
456 .await
457 .map_err(|e| {
458 OperationError::Internal(format!("error getting value: {}", e.to_string()))
459 })?;
460
461 Ok(value)
462 }
463 .boxed_local()
464 }
465
466 pub fn repository_get_setting(
467 object: &Repository,
468 operation: GetSetting,
469 state: DatabaseBackend,
470 ) -> LocalBoxFuture<'static, Result<Value, OperationError<GetSettingError>>> {
471 let object = object.clone();
472
473 async move {
474 let mut repository_backend = state.repository_backend.lock().await;
475 let value = repository_backend
476 .get_setting(&object, &operation.setting_name)
477 .await
478 .map_err(|e| OperationError::Internal(e.to_string()))?;
479
480 Ok(value.0)
481 }
482 .boxed_local()
483 }
484
485 pub fn instance_authentication_request(
486 object: &Instance,
487 operation: AuthenticationTokenRequest,
488 state: DatabaseBackend,
489 // Authorizes the request for SAME-INSTANCE
490 _authorized_instance: AuthorizedInstance,
491 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
492 let object = object.clone();
493 async move {
494 let mut backend = state.user_backend.lock().await;
495
496 backend
497 .login(&object, operation)
498 .await
499 .map_err(|e| OperationError::Internal(e.to_string()))
500 }
501 .boxed_local()
502 }
503
504 pub fn instance_registration_request(
505 _object: &Instance,
506 operation: RegisterAccountRequest,
507 state: DatabaseBackend,
508 // Authorizes the request for SAME-INSTANCE
509 _authorized_instance: AuthorizedInstance,
510 ) -> LocalBoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
511 async move {
512 let mut backend = state.user_backend.lock().await;
513
514 backend
515 .register(operation)
516 .await
517 .map_err(|e| OperationError::Internal(e.to_string()))
518 }
519 .boxed_local()
520 }
521
522 pub fn instance_create_repository_request(
523 _object: &Instance,
524 operation: RepositoryCreateRequest,
525 state: DatabaseBackend,
526 requester: AuthenticatedUser,
527 // Authorizes the request for SAME-INSTANCE
528 _authorized_instance: AuthorizedInstance,
529 ) -> LocalBoxFuture<'static, Result<Repository, OperationError<InstanceError>>> {
530 async move {
531 let mut backend = state.repository_backend.lock().await;
532
533 backend
534 .create_repository(&requester, &operation)
535 .await
536 .map_err(|e| OperationError::Internal(e.to_string()))
537 }
538 .boxed_local()
539 }
540
541 pub fn user_get_value_display_name(
542 object: &User,
543 operation: GetValueTyped<DisplayName>,
544 state: DatabaseBackend,
545 // _requester: AuthorizedUser,
546 ) -> LocalBoxFuture<'static, Result<DisplayName, OperationError<GetValueError>>> {
547 let object = object.clone();
548
549 async move {
550 let mut backend = state.user_backend.lock().await;
551
552 let raw_value = backend
553 .get_value(&object, &operation.value_name)
554 .await
555 .map_err(|e| OperationError::Internal(e.to_string()))?;
556
557 Ok(serde_json::from_value(raw_value.into_inner())
558 .map_err(|e| OperationError::Internal(e.to_string()))?)
559 }
560 .boxed_local()
561 }
562
563 pub fn user_get_value_bio(
564 object: &User,
565 operation: GetValueTyped<Bio>,
566 state: DatabaseBackend,
567 ) -> LocalBoxFuture<'static, Result<Bio, OperationError<GetValueError>>> {
568 let object = object.clone();
569
570 async move {
571 let mut backend = state.user_backend.lock().await;
572
573 let raw_value = backend
574 .get_value(&object, &operation.value_name)
575 .await
576 .map_err(|e| OperationError::Internal(e.to_string()))?;
577
578 Ok(serde_json::from_value(raw_value.into_inner())
579 .map_err(|e| OperationError::Internal(e.to_string()))?)
580 }
581 .boxed_local()
582 }
583
584 pub fn repository_get_value_description(
585 object: &Repository,
586 operation: GetValueTyped<Description>,
587 state: DatabaseBackend,
588 ) -> LocalBoxFuture<'static, Result<Description, OperationError<GetValueError>>> {
589 let object = object.clone();
590
591 async move {
592 let mut backend = state.repository_backend.lock().await;
593
594 let raw_value = backend
595 .get_value(&object, &operation.value_name)
596 .await
597 .map_err(|e| OperationError::Internal(e.to_string()))?;
598
599 Ok(serde_json::from_value(raw_value.into_inner())
600 .map_err(|e| OperationError::Internal(e.to_string()))?)
601 }
602 .boxed_local()
603 }
604
605 pub fn repository_get_value_visibility(
606 object: &Repository,
607 operation: GetValueTyped<Visibility>,
608 state: DatabaseBackend,
609 ) -> LocalBoxFuture<'static, Result<Visibility, OperationError<GetValueError>>> {
610 let object = object.clone();
611
612 async move {
613 let mut backend = state.repository_backend.lock().await;
614
615 let raw_value = backend
616 .get_value(&object, &operation.value_name)
617 .await
618 .map_err(|e| OperationError::Internal(e.to_string()))?;
619
620 Ok(serde_json::from_value(raw_value.into_inner())
621 .map_err(|e| OperationError::Internal(e.to_string()))?)
622 }
623 .boxed_local()
624 }
625
626 pub fn repository_get_default_branch(
627 object: &Repository,
628 operation: GetValueTyped<DefaultBranch>,
629 state: DatabaseBackend,
630 ) -> LocalBoxFuture<'static, Result<DefaultBranch, OperationError<GetValueError>>> {
631 let object = object.clone();
632
633 async move {
634 let mut backend = state.repository_backend.lock().await;
635
636 let raw_value = backend
637 .get_value(&object, &operation.value_name)
638 .await
639 .map_err(|e| OperationError::Internal(e.to_string()))?;
640
641 Ok(serde_json::from_value(raw_value.into_inner())
642 .map_err(|e| OperationError::Internal(e.to_string()))?)
643 }
644 .boxed_local()
645 }
646
647 pub fn repository_get_latest_commit(
648 object: &Repository,
649 operation: GetValueTyped<LatestCommit>,
650 state: DatabaseBackend,
651 ) -> LocalBoxFuture<'static, Result<LatestCommit, OperationError<GetValueError>>> {
652 let object = object.clone();
653
654 async move {
655 let mut backend = state.repository_backend.lock().await;
656
657 let raw_value = backend
658 .get_value(&object, &operation.value_name)
659 .await
660 .map_err(|e| OperationError::Internal(e.to_string()))?;
661
662 Ok(serde_json::from_value(raw_value.into_inner())
663 .map_err(|e| OperationError::Internal(e.to_string()))?)
664 }
665 .boxed_local()
666 }
667