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-daemon/src/database_backend/handler.rs⁩ - ⁨15525⁩ bytes
Raw
1 use std::{error::Error, sync::Arc};
2
3 use futures_util::{future::BoxFuture, 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,
13 RepositoryCommitBeforeRequest, RepositoryDiff, RepositoryDiffPatchRequest,
14 RepositoryDiffRequest, RepositoryFile, RepositoryFileFromIdRequest,
15 RepositoryFileFromPathRequest, RepositoryFileInspectRequest, RepositoryInfoRequest,
16 RepositorySummary, RepositoryView, Visibility,
17 },
18 settings::{AnySetting, GetSetting, GetSettingError},
19 user::{Bio, DisplayName, User, UserRepositoriesRequest},
20 value::{AnyValue, GetValue},
21 };
22 use giterated_stack::{
23 runtime::GiteratedRuntime, AuthenticatedUser, AuthorizedInstance, AuthorizedUser,
24 StackOperationState,
25 };
26
27 use super::DatabaseBackend;
28
29 pub fn user_get_repositories(
30 object: &User,
31 _operation: UserRepositoriesRequest,
32 state: DatabaseBackend,
33 _operation_state: StackOperationState,
34 requester: Option<AuthenticatedUser>,
35 ) -> BoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
36 let object = object.clone();
37
38 async move {
39 let mut user_backend = state.user_backend.lock().await;
40 let repositories_response = user_backend
41 .repositories_for_user(&requester, &object)
42 .await
43 .map_err(|e| OperationError::Internal(e.to_string()))?;
44 drop(user_backend);
45 let mut repositories_backend = state.repository_backend.lock().await;
46
47 let mut repositories = vec![];
48
49 for repository in repositories_response {
50 if repositories_backend
51 .exists(&requester, &repository.repository)
52 .await
53 .map_err(|e| OperationError::Internal(e.to_string()))?
54 {
55 repositories.push(repository);
56 }
57 }
58
59 Ok(repositories)
60 }
61 .boxed()
62 }
63
64 pub fn user_get_value(
65 object: &User,
66 operation: GetValue<AnyValue<User>>,
67 state: DatabaseBackend,
68 ) -> BoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
69 let object = object.clone();
70
71 async move {
72 let mut user_backend = state.user_backend.lock().await;
73 let value = user_backend
74 .get_value(&object, &operation.value_name)
75 .await
76 .map_err(|e| OperationError::Internal(e.to_string()))?;
77
78 Ok(value)
79 }
80 .boxed()
81 }
82
83 pub fn user_get_setting(
84 object: &User,
85 operation: GetSetting,
86 state: DatabaseBackend,
87 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
88 let object = object.clone();
89
90 async move {
91 let mut user_backend = state.user_backend.lock().await;
92 let value = user_backend
93 .get_setting(&object, &operation.setting_name)
94 .await
95 .map_err(|e| OperationError::Internal(e.to_string()))?;
96
97 Ok(value)
98 }
99 .boxed()
100 }
101
102 pub fn repository_info(
103 object: &Repository,
104 operation: RepositoryInfoRequest,
105 state: DatabaseBackend,
106 operation_state: StackOperationState,
107 backend: Arc<GiteratedRuntime>,
108 requester: Option<AuthenticatedUser>,
109 ) -> BoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
110 let object = object.clone();
111
112 async move {
113 let mut object = backend
114 .get_object::<Repository>(&object.to_string(), &operation_state)
115 .await
116 .unwrap();
117
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 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
131 drop(repository_backend);
132
133 let info = RepositoryView {
134 name: object.object().name.clone(),
135 owner: object.object().owner.clone(),
136 description: object.get::<Description>(&operation_state).await.ok(),
137 visibility: object
138 .get::<Visibility>(&operation_state)
139 .await
140 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
141 default_branch: object
142 .get::<DefaultBranch>(&operation_state)
143 .await
144 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
145 // 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.
146 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
147 tree_rev: operation.rev,
148 tree,
149 };
150
151 Ok(info)
152 }
153 .boxed()
154 }
155
156 pub fn repository_file_from_id(
157 object: &Repository,
158 operation: RepositoryFileFromIdRequest,
159 state: DatabaseBackend,
160 operation_state: StackOperationState,
161 backend: Arc<GiteratedRuntime>,
162
163 requester: Option<AuthenticatedUser>,
164 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
165 let object = object.clone();
166
167 async move {
168 let object = backend
169 .get_object::<Repository>(&object.to_string(), &operation_state)
170 .await
171 .unwrap();
172
173 let mut repository_backend = state.repository_backend.lock().await;
174 let file = repository_backend
175 .repository_file_from_id(
176 &requester,
177 object.object(),
178 &RepositoryFileFromIdRequest(operation.0),
179 )
180 .await
181 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
182 drop(repository_backend);
183
184 Ok(file)
185 }
186 .boxed()
187 }
188
189 pub fn repository_file_from_path(
190 object: &Repository,
191 operation: RepositoryFileFromPathRequest,
192 state: DatabaseBackend,
193 operation_state: StackOperationState,
194 backend: Arc<GiteratedRuntime>,
195 requester: Option<AuthenticatedUser>,
196 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
197 let object = object.clone();
198
199 async move {
200 let object = backend
201 .get_object::<Repository>(&object.to_string(), &operation_state)
202 .await
203 .unwrap();
204
205 let mut repository_backend = state.repository_backend.lock().await;
206 let file = repository_backend
207 .repository_file_from_path(
208 &requester,
209 object.object(),
210 &RepositoryFileFromPathRequest {
211 rev: operation.rev,
212 path: operation.path,
213 },
214 )
215 .await
216 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
217 drop(repository_backend);
218
219 Ok(file)
220 }
221 .boxed()
222 }
223
224 pub fn repository_diff(
225 object: &Repository,
226 operation: RepositoryDiffRequest,
227 state: DatabaseBackend,
228 operation_state: StackOperationState,
229 backend: Arc<GiteratedRuntime>,
230 requester: Option<AuthenticatedUser>,
231 ) -> BoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
232 let object = object.clone();
233
234 async move {
235 let object = backend
236 .get_object::<Repository>(&object.to_string(), &operation_state)
237 .await
238 .unwrap();
239
240 let mut repository_backend = state.repository_backend.lock().await;
241 let diff = repository_backend
242 .repository_diff(&requester, object.object(), &operation)
243 .await
244 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
245 drop(repository_backend);
246
247 Ok(diff)
248 }
249 .boxed()
250 }
251
252 pub fn repository_diff_patch(
253 object: &Repository,
254 operation: RepositoryDiffPatchRequest,
255 state: DatabaseBackend,
256 operation_state: StackOperationState,
257 backend: Arc<GiteratedRuntime>,
258 requester: Option<AuthenticatedUser>,
259 ) -> BoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
260 let object = object.clone();
261
262 async move {
263 let object = backend
264 .get_object::<Repository>(&object.to_string(), &operation_state)
265 .await
266 .unwrap();
267
268 let mut repository_backend = state.repository_backend.lock().await;
269 let patch = repository_backend
270 .repository_diff_patch(&requester, object.object(), &operation)
271 .await
272 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
273 drop(repository_backend);
274
275 Ok(patch)
276 }
277 .boxed()
278 }
279
280 pub fn repository_commit_before(
281 object: &Repository,
282 operation: RepositoryCommitBeforeRequest,
283 state: DatabaseBackend,
284 operation_state: StackOperationState,
285 backend: Arc<GiteratedRuntime>,
286 requester: Option<AuthenticatedUser>,
287 ) -> BoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
288 let object = object.clone();
289
290 async move {
291 let object = backend
292 .get_object::<Repository>(&object.to_string(), &operation_state)
293 .await
294 .unwrap();
295
296 let mut repository_backend = state.repository_backend.lock().await;
297 let file = repository_backend
298 .repository_commit_before(&requester, object.object(), &operation)
299 .await
300 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
301 drop(repository_backend);
302
303 Ok(file)
304 }
305 .boxed()
306 }
307
308 pub fn repository_get_value(
309 object: &Repository,
310 operation: GetValue<AnyValue<Repository>>,
311 state: DatabaseBackend,
312 ) -> BoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
313 let object = object.clone();
314
315 async move {
316 let mut repository_backend = state.repository_backend.lock().await;
317 let value = repository_backend
318 .get_value(&object, &operation.value_name)
319 .await
320 .map_err(|e| {
321 OperationError::Internal(format!("error getting value: {}", e.to_string()))
322 })?;
323
324 Ok(value)
325 }
326 .boxed()
327 }
328
329 pub fn repository_get_setting(
330 object: &Repository,
331 operation: GetSetting,
332 state: DatabaseBackend,
333 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
334 let object = object.clone();
335
336 async move {
337 let mut repository_backend = state.repository_backend.lock().await;
338 let value = repository_backend
339 .get_setting(&object, &operation.setting_name)
340 .await
341 .map_err(|e| OperationError::Internal(e.to_string()))?;
342
343 Ok(value)
344 }
345 .boxed()
346 }
347
348 pub fn instance_authentication_request(
349 object: &Instance,
350 operation: AuthenticationTokenRequest,
351 state: DatabaseBackend,
352 // Authorizes the request for SAME-INSTANCE
353 _authorized_instance: AuthorizedInstance,
354 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
355 let object = object.clone();
356 async move {
357 let mut backend = state.user_backend.lock().await;
358
359 backend
360 .login(&object, operation)
361 .await
362 .map_err(|e| OperationError::Internal(e.to_string()))
363 }
364 .boxed()
365 }
366
367 pub fn instance_registration_request(
368 _object: &Instance,
369 operation: RegisterAccountRequest,
370 state: DatabaseBackend,
371 // Authorizes the request for SAME-INSTANCE
372 _authorized_instance: AuthorizedInstance,
373 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
374 async move {
375 let mut backend = state.user_backend.lock().await;
376
377 backend
378 .register(operation)
379 .await
380 .map_err(|e| OperationError::Internal(e.to_string()))
381 }
382 .boxed()
383 }
384
385 pub fn instance_create_repository_request(
386 _object: &Instance,
387 operation: RepositoryCreateRequest,
388 state: DatabaseBackend,
389 requester: AuthenticatedUser,
390 // Authorizes the request for SAME-INSTANCE
391 _authorized_instance: AuthorizedInstance,
392 ) -> BoxFuture<'static, Result<Repository, OperationError<InstanceError>>> {
393 async move {
394 let mut backend = state.repository_backend.lock().await;
395
396 backend
397 .create_repository(&requester, &operation)
398 .await
399 .map_err(|e| OperationError::Internal(e.to_string()))
400 }
401 .boxed()
402 }
403
404 pub fn user_get_value_display_name(
405 object: &User,
406 operation: GetValue<DisplayName>,
407 state: DatabaseBackend,
408 _requester: AuthorizedUser,
409 ) -> BoxFuture<'static, Result<DisplayName, OperationError<GetValueError>>> {
410 let object = object.clone();
411
412 async move {
413 let mut backend = state.user_backend.lock().await;
414
415 let raw_value = backend
416 .get_value(&object, &operation.value_name)
417 .await
418 .map_err(|e| OperationError::Internal(e.to_string()))?;
419
420 Ok(serde_json::from_value(raw_value.into_inner())
421 .map_err(|e| OperationError::Internal(e.to_string()))?)
422 }
423 .boxed()
424 }
425
426 pub fn user_get_value_bio(
427 object: &User,
428 operation: GetValue<Bio>,
429 state: DatabaseBackend,
430 ) -> BoxFuture<'static, Result<Bio, OperationError<GetValueError>>> {
431 let object = object.clone();
432
433 async move {
434 let mut backend = state.user_backend.lock().await;
435
436 let raw_value = backend
437 .get_value(&object, &operation.value_name)
438 .await
439 .map_err(|e| OperationError::Internal(e.to_string()))?;
440
441 Ok(serde_json::from_value(raw_value.into_inner())
442 .map_err(|e| OperationError::Internal(e.to_string()))?)
443 }
444 .boxed()
445 }
446
447 pub fn repository_get_value_description(
448 object: &Repository,
449 operation: GetValue<Description>,
450 state: DatabaseBackend,
451 ) -> BoxFuture<'static, Result<Description, OperationError<GetValueError>>> {
452 let object = object.clone();
453
454 async move {
455 let mut backend = state.repository_backend.lock().await;
456
457 let raw_value = backend
458 .get_value(&object, &operation.value_name)
459 .await
460 .map_err(|e| OperationError::Internal(e.to_string()))?;
461
462 Ok(serde_json::from_value(raw_value.into_inner())
463 .map_err(|e| OperationError::Internal(e.to_string()))?)
464 }
465 .boxed()
466 }
467
468 pub fn repository_get_value_visibility(
469 object: &Repository,
470 operation: GetValue<Visibility>,
471 state: DatabaseBackend,
472 ) -> BoxFuture<'static, Result<Visibility, OperationError<GetValueError>>> {
473 let object = object.clone();
474
475 async move {
476 let mut backend = state.repository_backend.lock().await;
477
478 let raw_value = backend
479 .get_value(&object, &operation.value_name)
480 .await
481 .map_err(|e| OperationError::Internal(e.to_string()))?;
482
483 Ok(serde_json::from_value(raw_value.into_inner())
484 .map_err(|e| OperationError::Internal(e.to_string()))?)
485 }
486 .boxed()
487 }
488