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

ambee/giterated

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

Major refactor to handler traits

Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Squashed commit of the following: commit 62e1ecf76ee31cda0bab4602d9d00fa0dc2f9158 Author: Amber <[email protected]> Date: Wed Oct 11 09:31:11 2023 -0500 Update commit dfd2d1b0b5d81ee3bc48f0321c6aceaa677e3b8b Author: Amber <[email protected]> Date: Wed Oct 11 09:31:07 2023 -0500 Major refactor to handler traits Added `IntoGiteratedHandler`, which is the new trait for handler functions. This allows us to finally get rid of the Object and ObjectOperation bounds that resulted in hacks around the newer features of the unified stack. Removed dead and legacy code. I think... commit 57b4b398eff32e69f2f4b9700e42a1277a4d1055 Author: Amber <[email protected]> Date: Sun Oct 1 23:05:10 2023 -0500 New handler trait for giterated stack Refactor the old handler trait so it is more generic and can be used for specific kinds of handlers

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨90c4780

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨12757⁩ bytes
Raw
1 use std::sync::Arc;
2
3 use giterated_models::{
4 authenticated::UserAuthenticationToken,
5 error::{InstanceError, IntoInternalError, OperationError, RepositoryError, UserError},
6 instance::{
7 AuthenticationTokenRequest, Instance, RegisterAccountRequest, RepositoryCreateRequest,
8 },
9 object_backend::ObjectBackend,
10 repository::{
11 Commit, DefaultBranch, Description, LatestCommit, Repository, RepositoryBranch,
12 RepositoryBranchesRequest, RepositoryCommitBeforeRequest, RepositoryCommitFromIdRequest,
13 RepositoryDiff, RepositoryDiffPatchRequest, RepositoryDiffRequest, RepositoryFile,
14 RepositoryFileFromIdRequest, RepositoryFileFromPathRequest, RepositoryFileInspectRequest,
15 RepositoryInfoRequest, RepositoryLastCommitOfFileRequest, RepositoryStatistics,
16 RepositoryStatisticsRequest, RepositorySummary, RepositoryView, Visibility,
17 },
18 user::{User, UserRepositoriesRequest},
19 };
20 use giterated_stack::{AuthenticatedUser, GiteratedStack, StackOperationState};
21
22 use super::DatabaseBackend;
23
24 pub async fn user_get_repositories(
25 object: User,
26 _operation: UserRepositoriesRequest,
27 state: DatabaseBackend,
28 _operation_state: StackOperationState,
29 requester: Option<AuthenticatedUser>,
30 ) -> Result<Vec<RepositorySummary>, OperationError<UserError>> {
31 let object = object.clone();
32
33 let mut user_backend = state.user_backend.lock().await;
34 let repositories_response = user_backend
35 .repositories_for_user(&requester, &object)
36 .await
37 .as_internal_error()?;
38 drop(user_backend);
39 let mut repositories_backend = state.repository_backend.lock().await;
40
41 let mut repositories = vec![];
42
43 for repository in repositories_response {
44 if repositories_backend
45 .exists(&requester, &repository.repository)
46 .await
47 .as_internal_error()?
48 {
49 repositories.push(repository);
50 }
51 }
52
53 Ok(repositories)
54 }
55
56 pub async fn repository_info(
57 object: Repository,
58 operation: RepositoryInfoRequest,
59 state: DatabaseBackend,
60 operation_state: StackOperationState,
61 backend: Arc<GiteratedStack>,
62 requester: Option<AuthenticatedUser>,
63 ) -> Result<RepositoryView, OperationError<RepositoryError>> {
64 let mut object = backend
65 .get_object::<Repository>(&object.to_string(), &operation_state)
66 .await
67 .unwrap();
68 let mut repository_backend = state.repository_backend.lock().await;
69 let tree = repository_backend
70 .repository_file_inspect(
71 &requester,
72 object.object(),
73 &RepositoryFileInspectRequest {
74 extra_metadata: operation.extra_metadata,
75 path: operation.path.clone(),
76 rev: operation.rev.clone(),
77 },
78 )
79 .await
80 .as_internal_error()?;
81
82 let statistics = repository_backend
83 .repository_get_statistics(
84 &requester,
85 object.object(),
86 &RepositoryStatisticsRequest {
87 rev: operation.rev.clone(),
88 },
89 )
90 .await
91 .as_internal_error()?;
92 drop(repository_backend);
93
94 let info = RepositoryView {
95 name: object.object().name.clone(),
96 owner: object.object().owner.clone(),
97 description: object.get::<Description>(&operation_state).await.ok(),
98 visibility: object
99 .get::<Visibility>(&operation_state)
100 .await
101 .as_internal_error()?,
102 default_branch: object
103 .get::<DefaultBranch>(&operation_state)
104 .await
105 .as_internal_error()?,
106 // 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.
107 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
108 stats: statistics,
109 tree_rev: operation.rev.clone(),
110 tree,
111 };
112
113 Ok(info)
114 }
115
116 pub async fn repository_get_statistics(
117 object: Repository,
118 operation: RepositoryStatisticsRequest,
119 state: DatabaseBackend,
120 operation_state: StackOperationState,
121 backend: Arc<GiteratedStack>,
122 requester: Option<AuthenticatedUser>,
123 ) -> Result<RepositoryStatistics, OperationError<RepositoryError>> {
124 let object = backend
125 .get_object::<Repository>(&object.to_string(), &operation_state)
126 .await
127 .unwrap();
128
129 let mut repository_backend = state.repository_backend.lock().await;
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 .as_internal_error()?;
140 drop(repository_backend);
141
142 Ok(statistics)
143 }
144
145 pub async fn repository_get_branches(
146 object: Repository,
147 operation: RepositoryBranchesRequest,
148 state: DatabaseBackend,
149 operation_state: StackOperationState,
150 backend: Arc<GiteratedStack>,
151 requester: Option<AuthenticatedUser>,
152 ) -> Result<Vec<RepositoryBranch>, OperationError<RepositoryError>> {
153 let object = backend
154 .get_object::<Repository>(&object.to_string(), &operation_state)
155 .await
156 .unwrap();
157
158 let mut repository_backend = state.repository_backend.lock().await;
159 let branches = repository_backend
160 .repository_get_branches(&requester, object.object(), &operation)
161 .await
162 .as_internal_error()?;
163 drop(repository_backend);
164
165 Ok(branches)
166 }
167
168 pub async fn repository_file_from_id(
169 object: Repository,
170 operation: RepositoryFileFromIdRequest,
171 state: DatabaseBackend,
172 operation_state: StackOperationState,
173 backend: Arc<GiteratedStack>,
174
175 requester: Option<AuthenticatedUser>,
176 ) -> Result<RepositoryFile, OperationError<RepositoryError>> {
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 file = repository_backend
184 .repository_file_from_id(
185 &requester,
186 object.object(),
187 &RepositoryFileFromIdRequest(operation.0.clone()),
188 )
189 .await
190 .as_internal_error()?;
191 drop(repository_backend);
192
193 Ok(file)
194 }
195
196 pub async fn repository_file_from_path(
197 object: Repository,
198 operation: RepositoryFileFromPathRequest,
199 state: DatabaseBackend,
200 operation_state: StackOperationState,
201 backend: Arc<GiteratedStack>,
202 requester: Option<AuthenticatedUser>,
203 ) -> Result<(RepositoryFile, String), OperationError<RepositoryError>> {
204 let object = backend
205 .get_object::<Repository>(&object.to_string(), &operation_state)
206 .await
207 .unwrap();
208
209 let mut repository_backend = state.repository_backend.lock().await;
210 let file = repository_backend
211 .repository_file_from_path(
212 &requester,
213 object.object(),
214 &RepositoryFileFromPathRequest {
215 rev: operation.rev.clone(),
216 path: operation.path.clone(),
217 },
218 )
219 .await
220 .as_internal_error()?;
221 drop(repository_backend);
222
223 Ok(file)
224 }
225
226 pub async fn repository_last_commit_of_file(
227 object: Repository,
228 operation: RepositoryLastCommitOfFileRequest,
229 state: DatabaseBackend,
230 operation_state: StackOperationState,
231 backend: Arc<GiteratedStack>,
232 requester: Option<AuthenticatedUser>,
233 ) -> Result<Commit, OperationError<RepositoryError>> {
234 let object = backend
235 .get_object::<Repository>(&object.to_string(), &operation_state)
236 .await
237 .unwrap();
238
239 let mut repository_backend = state.repository_backend.lock().await;
240 let commit = repository_backend
241 .repository_last_commit_of_file(
242 &requester,
243 object.object(),
244 &RepositoryLastCommitOfFileRequest {
245 start_commit: operation.start_commit.clone(),
246 path: operation.path.clone(),
247 },
248 )
249 .await
250 .as_internal_error()?;
251 drop(repository_backend);
252
253 Ok(commit)
254 }
255
256 pub async fn repository_commit_by_id(
257 object: Repository,
258 operation: RepositoryCommitFromIdRequest,
259 state: DatabaseBackend,
260 operation_state: StackOperationState,
261 backend: Arc<GiteratedStack>,
262 requester: Option<AuthenticatedUser>,
263 ) -> Result<Commit, OperationError<RepositoryError>> {
264 let object = backend
265 .get_object::<Repository>(&object.to_string(), &operation_state)
266 .await
267 .unwrap();
268
269 let mut repository_backend = state.repository_backend.lock().await;
270 let commit = repository_backend
271 .repository_commit_from_id(
272 &requester,
273 object.object(),
274 &RepositoryCommitFromIdRequest(operation.0.clone()),
275 )
276 .await
277 .as_internal_error()?;
278 drop(repository_backend);
279
280 Ok(commit)
281 }
282
283 pub async fn repository_diff(
284 object: Repository,
285 operation: RepositoryDiffRequest,
286 state: DatabaseBackend,
287 operation_state: StackOperationState,
288 backend: Arc<GiteratedStack>,
289 requester: Option<AuthenticatedUser>,
290 ) -> Result<RepositoryDiff, OperationError<RepositoryError>> {
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 diff = repository_backend
298 .repository_diff(&requester, object.object(), &operation)
299 .await
300 .as_internal_error()?;
301 drop(repository_backend);
302
303 Ok(diff)
304 }
305
306 pub async fn repository_diff_patch(
307 object: Repository,
308 operation: RepositoryDiffPatchRequest,
309 state: DatabaseBackend,
310 operation_state: StackOperationState,
311 backend: Arc<GiteratedStack>,
312 requester: Option<AuthenticatedUser>,
313 ) -> Result<String, OperationError<RepositoryError>> {
314 let object = backend
315 .get_object::<Repository>(&object.to_string(), &operation_state)
316 .await
317 .unwrap();
318
319 let mut repository_backend = state.repository_backend.lock().await;
320 let patch = repository_backend
321 .repository_diff_patch(&requester, object.object(), &operation)
322 .await
323 .as_internal_error()?;
324 drop(repository_backend);
325
326 Ok(patch)
327 }
328
329 pub async fn repository_commit_before(
330 object: Repository,
331 operation: RepositoryCommitBeforeRequest,
332 state: DatabaseBackend,
333 operation_state: StackOperationState,
334 backend: Arc<GiteratedStack>,
335 requester: Option<AuthenticatedUser>,
336 ) -> Result<Commit, OperationError<RepositoryError>> {
337 let object = backend
338 .get_object::<Repository>(&object.to_string(), &operation_state)
339 .await
340 .unwrap();
341
342 let mut repository_backend = state.repository_backend.lock().await;
343 let file = repository_backend
344 .repository_commit_before(&requester, object.object(), &operation)
345 .await
346 .as_internal_error()?;
347 drop(repository_backend);
348
349 Ok(file)
350 }
351
352 pub async fn instance_authentication_request(
353 object: Instance,
354 operation: AuthenticationTokenRequest,
355 state: DatabaseBackend,
356 _operation_state: StackOperationState,
357 // Authorizes the request for SAME-INSTANCE
358 // _authorized_instance: AuthorizedInstance,
359 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
360 let mut backend = state.user_backend.lock().await;
361
362 backend
363 .login(&object, operation.clone())
364 .await
365 .as_internal_error()
366 }
367
368 pub async fn instance_registration_request(
369 _object: Instance,
370 operation: RegisterAccountRequest,
371 state: DatabaseBackend,
372 _operation_state: StackOperationState, // Authorizes the request for SAME-INSTANCE
373 // _authorized_instance: AuthorizedInstance,
374 ) -> Result<UserAuthenticationToken, OperationError<InstanceError>> {
375 let mut backend = state.user_backend.lock().await;
376
377 backend
378 .register(operation.clone())
379 .await
380 .as_internal_error()
381 }
382
383 pub async fn instance_create_repository_request(
384 _object: Instance,
385 operation: RepositoryCreateRequest,
386 state: DatabaseBackend,
387 _operation_state: StackOperationState,
388 requester: AuthenticatedUser,
389 // Authorizes the request for SAME-INSTANCE
390 // _authorized_instance: AuthorizedInstance,
391 ) -> Result<Repository, OperationError<InstanceError>> {
392 let mut backend = state.repository_backend.lock().await;
393
394 backend
395 .create_repository(&requester, &operation)
396 .await
397 .as_internal_error()
398 }
399