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

ambee/giterated

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

Add authentication back into the operation states

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨97a26fd

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨12795⁩ bytes
Raw
1 use std::error::Error;
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, SetSetting, SetSettingError},
19 user::{User, UserRepositoriesRequest},
20 value::{AnyValue, GetValue},
21 };
22 use giterated_stack::{BackendWrapper, StackOperationState};
23
24 use super::DatabaseBackend;
25
26 pub fn user_get_repositories(
27 object: &User,
28 _operation: UserRepositoriesRequest,
29 state: DatabaseBackend,
30 ) -> BoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
31 let object = object.clone();
32
33 async move {
34 let mut user_backend = state.user_backend.lock().await;
35 let repositories = user_backend
36 .repositories_for_user(None, &object)
37 .await
38 .map_err(|e| OperationError::Internal(e.to_string()))?;
39
40 Ok(repositories)
41 }
42 .boxed()
43 }
44
45 pub fn user_get_value(
46 object: &User,
47 operation: GetValue<AnyValue<User>>,
48 state: DatabaseBackend,
49 ) -> BoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
50 let object = object.clone();
51
52 async move {
53 let mut user_backend = state.user_backend.lock().await;
54 let value = user_backend
55 .get_value(&object, &operation.value_name)
56 .await
57 .map_err(|e| OperationError::Internal(e.to_string()))?;
58
59 Ok(value)
60 }
61 .boxed()
62 }
63
64 pub fn user_get_setting(
65 object: &User,
66 operation: GetSetting<AnySetting>,
67 state: DatabaseBackend,
68 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
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_setting(&object, &operation.setting_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_set_setting(
84 object: &User,
85 operation: SetSetting<AnySetting>,
86 state: DatabaseBackend,
87 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
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 .write_setting(&object, &operation.setting_name, &operation.value.0)
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: BackendWrapper,
108 ) -> BoxFuture<'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
117 let mut repository_backend = state.repository_backend.lock().await;
118 let tree = repository_backend
119 .repository_file_inspect(
120 None,
121 object.object(),
122 &RepositoryFileInspectRequest {
123 extra_metadata: operation.extra_metadata,
124 path: operation.path,
125 rev: operation.rev.clone(),
126 },
127 )
128 .await
129 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
130 drop(repository_backend);
131
132 let info = RepositoryView {
133 name: object.object().name.clone(),
134 owner: object.object().owner.clone(),
135 description: object.get::<Description>(&operation_state).await.ok(),
136 visibility: object
137 .get::<Visibility>(&operation_state)
138 .await
139 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
140 default_branch: object
141 .get::<DefaultBranch>(&operation_state)
142 .await
143 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
144 // 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.
145 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
146 tree_rev: operation.rev,
147 tree,
148 };
149
150 Ok(info)
151 }
152 .boxed()
153 }
154
155 pub fn repository_file_from_id(
156 object: &Repository,
157 operation: RepositoryFileFromIdRequest,
158 state: DatabaseBackend,
159 operation_state: StackOperationState,
160 backend: BackendWrapper,
161 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
162 let object = object.clone();
163
164 async move {
165 let object = backend
166 .get_object::<Repository>(&object.to_string(), &operation_state)
167 .await
168 .unwrap();
169
170 let mut repository_backend = state.repository_backend.lock().await;
171 let file = repository_backend
172 .repository_file_from_id(
173 None,
174 object.object(),
175 &RepositoryFileFromIdRequest(operation.0),
176 )
177 .await
178 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
179 drop(repository_backend);
180
181 Ok(file)
182 }
183 .boxed()
184 }
185
186 pub fn repository_file_from_path(
187 object: &Repository,
188 operation: RepositoryFileFromPathRequest,
189 state: DatabaseBackend,
190 operation_state: StackOperationState,
191 backend: BackendWrapper,
192 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
193 let object = object.clone();
194
195 async move {
196 let object = backend
197 .get_object::<Repository>(&object.to_string(), &operation_state)
198 .await
199 .unwrap();
200
201 let mut repository_backend = state.repository_backend.lock().await;
202 let file = repository_backend
203 .repository_file_from_path(
204 None,
205 object.object(),
206 &RepositoryFileFromPathRequest {
207 rev: operation.rev,
208 path: operation.path,
209 },
210 )
211 .await
212 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
213 drop(repository_backend);
214
215 Ok(file)
216 }
217 .boxed()
218 }
219
220 pub fn repository_diff(
221 object: &Repository,
222 operation: RepositoryDiffRequest,
223 state: DatabaseBackend,
224 operation_state: StackOperationState,
225 backend: BackendWrapper,
226 ) -> BoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
227 let object = object.clone();
228
229 async move {
230 let object = backend
231 .get_object::<Repository>(&object.to_string(), &operation_state)
232 .await
233 .unwrap();
234
235 let mut repository_backend = state.repository_backend.lock().await;
236 let diff = repository_backend
237 .repository_diff(None, object.object(), &operation)
238 .await
239 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
240 drop(repository_backend);
241
242 Ok(diff)
243 }
244 .boxed()
245 }
246
247 pub fn repository_diff_patch(
248 object: &Repository,
249 operation: RepositoryDiffPatchRequest,
250 state: DatabaseBackend,
251 operation_state: StackOperationState,
252 backend: BackendWrapper,
253 ) -> BoxFuture<'static, Result<String, OperationError<RepositoryError>>> {
254 let object = object.clone();
255
256 async move {
257 let object = backend
258 .get_object::<Repository>(&object.to_string(), &operation_state)
259 .await
260 .unwrap();
261
262 let mut repository_backend = state.repository_backend.lock().await;
263 let patch = repository_backend
264 .repository_diff_patch(None, object.object(), &operation)
265 .await
266 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
267 drop(repository_backend);
268
269 Ok(patch)
270 }
271 .boxed()
272 }
273
274 pub fn repository_commit_before(
275 object: &Repository,
276 operation: RepositoryCommitBeforeRequest,
277 state: DatabaseBackend,
278 operation_state: StackOperationState,
279 backend: BackendWrapper,
280 ) -> BoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
281 let object = object.clone();
282
283 async move {
284 let object = backend
285 .get_object::<Repository>(&object.to_string(), &operation_state)
286 .await
287 .unwrap();
288
289 let mut repository_backend = state.repository_backend.lock().await;
290 let file = repository_backend
291 .repository_commit_before(None, object.object(), &operation)
292 .await
293 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
294 drop(repository_backend);
295
296 Ok(file)
297 }
298 .boxed()
299 }
300
301 pub fn repository_get_value(
302 object: &Repository,
303 operation: GetValue<AnyValue<Repository>>,
304 state: DatabaseBackend,
305 ) -> BoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
306 let object = object.clone();
307
308 async move {
309 let mut repository_backend = state.repository_backend.lock().await;
310 let value = repository_backend
311 .get_value(&object, &operation.value_name)
312 .await
313 .map_err(|e| {
314 OperationError::Internal(format!("error getting value: {}", e.to_string()))
315 })?;
316
317 Ok(value)
318 }
319 .boxed()
320 }
321
322 pub fn repository_get_setting(
323 object: &Repository,
324 operation: GetSetting<AnySetting>,
325 state: DatabaseBackend,
326 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
327 let object = object.clone();
328
329 async move {
330 let mut repository_backend = state.repository_backend.lock().await;
331 let value = repository_backend
332 .get_setting(&object, &operation.setting_name)
333 .await
334 .map_err(|e| OperationError::Internal(e.to_string()))?;
335
336 Ok(value)
337 }
338 .boxed()
339 }
340
341 pub fn repository_set_setting(
342 object: &Repository,
343 operation: SetSetting<AnySetting>,
344 state: DatabaseBackend,
345 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
346 let object = object.clone();
347
348 async move {
349 let mut repository_backend = state.repository_backend.lock().await;
350 let value = repository_backend
351 .write_setting(&object, &operation.setting_name, &operation.value.0)
352 .await
353 .map_err(|e| OperationError::Internal(e.to_string()))?;
354
355 Ok(value)
356 }
357 .boxed()
358 }
359
360 pub fn instance_authentication_request(
361 object: &Instance,
362 operation: AuthenticationTokenRequest,
363 state: DatabaseBackend,
364 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
365 let object = object.clone();
366 async move {
367 let mut backend = state.user_backend.lock().await;
368
369 backend
370 .login(&object, operation)
371 .await
372 .map_err(|e| OperationError::Internal(e.to_string()))
373 }
374 .boxed()
375 }
376
377 pub fn instance_registration_request(
378 _object: &Instance,
379 operation: RegisterAccountRequest,
380 state: DatabaseBackend,
381 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
382 async move {
383 let mut backend = state.user_backend.lock().await;
384
385 backend
386 .register(operation)
387 .await
388 .map_err(|e| OperationError::Internal(e.to_string()))
389 }
390 .boxed()
391 }
392
393 pub fn instance_create_repository_request(
394 _object: &Instance,
395 operation: RepositoryCreateRequest,
396 state: DatabaseBackend,
397 ) -> BoxFuture<'static, Result<Repository, OperationError<InstanceError>>> {
398 async move {
399 let mut backend = state.repository_backend.lock().await;
400
401 backend
402 .create_repository(&operation.owner, &operation)
403 .await
404 .map_err(|e| OperationError::Internal(e.to_string()))
405 }
406 .boxed()
407 }
408