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

ambee/giterated

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

Temporary latestcommit fix

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨73b32eb

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