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

ambee/giterated

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

Add authentication operations

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨c27b4f3

⁨giterated-daemon/src/database_backend/handler.rs⁩ - ⁨10351⁩ 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::{AuthenticationTokenRequest, Instance, RegisterAccountRequest},
8 object_backend::ObjectBackend,
9 repository::{
10 Commit, DefaultBranch, Description, LatestCommit, Repository,
11 RepositoryCommitBeforeRequest, RepositoryDiff, RepositoryDiffRequest, RepositoryFile,
12 RepositoryFileFromIdRequest, RepositoryFileInspectRequest, RepositoryInfoRequest,
13 RepositorySummary, RepositoryView, Visibility,
14 },
15 settings::{AnySetting, GetSetting, GetSettingError, SetSetting, SetSettingError},
16 user::{User, UserRepositoriesRequest},
17 value::{AnyValue, GetValue},
18 };
19 use giterated_stack::{BackendWrapper, StackOperationState};
20
21 use super::DatabaseBackend;
22
23 pub fn user_get_repositories(
24 object: &User,
25 _operation: UserRepositoriesRequest,
26 state: DatabaseBackend,
27 ) -> BoxFuture<'static, Result<Vec<RepositorySummary>, OperationError<UserError>>> {
28 let object = object.clone();
29
30 async move {
31 let mut user_backend = state.user_backend.lock().await;
32 let repositories = user_backend
33 .repositories_for_user(None, &object)
34 .await
35 .map_err(|e| OperationError::Internal(e.to_string()))?;
36
37 Ok(repositories)
38 }
39 .boxed()
40 }
41
42 pub fn user_get_value(
43 object: &User,
44 operation: GetValue<AnyValue<User>>,
45 state: DatabaseBackend,
46 ) -> BoxFuture<'static, Result<AnyValue<User>, OperationError<GetValueError>>> {
47 let object = object.clone();
48
49 async move {
50 let mut user_backend = state.user_backend.lock().await;
51 let value = user_backend
52 .get_value(&object, &operation.value_name)
53 .await
54 .map_err(|e| OperationError::Internal(e.to_string()))?;
55
56 Ok(value)
57 }
58 .boxed()
59 }
60
61 pub fn user_get_setting(
62 object: &User,
63 operation: GetSetting<AnySetting>,
64 state: DatabaseBackend,
65 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
66 let object = object.clone();
67
68 async move {
69 let mut user_backend = state.user_backend.lock().await;
70 let value = user_backend
71 .get_setting(&object, &operation.setting_name)
72 .await
73 .map_err(|e| OperationError::Internal(e.to_string()))?;
74
75 Ok(value)
76 }
77 .boxed()
78 }
79
80 pub fn user_set_setting(
81 object: &User,
82 operation: SetSetting<AnySetting>,
83 state: DatabaseBackend,
84 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
85 let object = object.clone();
86
87 async move {
88 let mut user_backend = state.user_backend.lock().await;
89 let value = user_backend
90 .write_setting(&object, &operation.setting_name, &operation.value.0)
91 .await
92 .map_err(|e| OperationError::Internal(e.to_string()))?;
93
94 Ok(value)
95 }
96 .boxed()
97 }
98
99 pub fn repository_info(
100 object: &Repository,
101 operation: RepositoryInfoRequest,
102 state: DatabaseBackend,
103 operation_state: StackOperationState,
104 backend: BackendWrapper,
105 ) -> BoxFuture<'static, Result<RepositoryView, OperationError<RepositoryError>>> {
106 let object = object.clone();
107
108 async move {
109 let mut object = backend
110 .get_object::<Repository>(&object.to_string(), &operation_state)
111 .await
112 .unwrap();
113
114 let mut repository_backend = state.repository_backend.lock().await;
115 let tree = repository_backend
116 .repository_file_inspect(
117 None,
118 object.object(),
119 &RepositoryFileInspectRequest {
120 extra_metadata: operation.extra_metadata,
121 path: operation.path,
122 rev: operation.rev.clone(),
123 },
124 )
125 .await
126 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
127 drop(repository_backend);
128
129 let info = RepositoryView {
130 name: object.object().name.clone(),
131 owner: object.object().owner.clone(),
132 description: object.get::<Description>(&operation_state).await.ok(),
133 visibility: object
134 .get::<Visibility>(&operation_state)
135 .await
136 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
137 default_branch: object
138 .get::<DefaultBranch>(&operation_state)
139 .await
140 .map_err(|e| OperationError::Internal(format!("{:?}: {}", e.source(), e)))?,
141 // 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.
142 latest_commit: object.get::<LatestCommit>(&operation_state).await.ok(),
143 tree_rev: operation.rev,
144 tree,
145 };
146
147 Ok(info)
148 }
149 .boxed()
150 }
151
152 pub fn repository_file_from_id(
153 object: &Repository,
154 operation: RepositoryFileFromIdRequest,
155 state: DatabaseBackend,
156 operation_state: StackOperationState,
157 backend: BackendWrapper,
158 ) -> BoxFuture<'static, Result<RepositoryFile, OperationError<RepositoryError>>> {
159 let object = object.clone();
160
161 async move {
162 let object = backend
163 .get_object::<Repository>(&object.to_string(), &operation_state)
164 .await
165 .unwrap();
166
167 let mut repository_backend = state.repository_backend.lock().await;
168 let file = repository_backend
169 .repository_file_from_id(
170 None,
171 object.object(),
172 &RepositoryFileFromIdRequest(operation.0),
173 )
174 .await
175 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
176 drop(repository_backend);
177
178 Ok(file)
179 }
180 .boxed()
181 }
182
183 pub fn repository_diff(
184 object: &Repository,
185 operation: RepositoryDiffRequest,
186 state: DatabaseBackend,
187 operation_state: StackOperationState,
188 backend: BackendWrapper,
189 ) -> BoxFuture<'static, Result<RepositoryDiff, OperationError<RepositoryError>>> {
190 let object = object.clone();
191
192 async move {
193 let object = backend
194 .get_object::<Repository>(&object.to_string(), &operation_state)
195 .await
196 .unwrap();
197
198 let mut repository_backend = state.repository_backend.lock().await;
199 let file = repository_backend
200 .repository_diff(None, object.object(), &operation)
201 .await
202 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
203 drop(repository_backend);
204
205 Ok(file)
206 }
207 .boxed()
208 }
209
210 pub fn repository_commit_before(
211 object: &Repository,
212 operation: RepositoryCommitBeforeRequest,
213 state: DatabaseBackend,
214 operation_state: StackOperationState,
215 backend: BackendWrapper,
216 ) -> BoxFuture<'static, Result<Commit, OperationError<RepositoryError>>> {
217 let object = object.clone();
218
219 async move {
220 let object = backend
221 .get_object::<Repository>(&object.to_string(), &operation_state)
222 .await
223 .unwrap();
224
225 let mut repository_backend = state.repository_backend.lock().await;
226 let file = repository_backend
227 .repository_commit_before(None, object.object(), &operation)
228 .await
229 .map_err(|err| OperationError::Internal(format!("{:?}", err)))?;
230 drop(repository_backend);
231
232 Ok(file)
233 }
234 .boxed()
235 }
236
237 pub fn repository_get_value(
238 object: &Repository,
239 operation: GetValue<AnyValue<Repository>>,
240 state: DatabaseBackend,
241 ) -> BoxFuture<'static, Result<AnyValue<Repository>, OperationError<GetValueError>>> {
242 let object = object.clone();
243
244 async move {
245 let mut repository_backend = state.repository_backend.lock().await;
246 let value = repository_backend
247 .get_value(&object, &operation.value_name)
248 .await
249 .map_err(|e| {
250 OperationError::Internal(format!("error getting value: {}", e.to_string()))
251 })?;
252
253 Ok(value)
254 }
255 .boxed()
256 }
257
258 pub fn repository_get_setting(
259 object: &Repository,
260 operation: GetSetting<AnySetting>,
261 state: DatabaseBackend,
262 ) -> BoxFuture<'static, Result<AnySetting, OperationError<GetSettingError>>> {
263 let object = object.clone();
264
265 async move {
266 let mut repository_backend = state.repository_backend.lock().await;
267 let value = repository_backend
268 .get_setting(&object, &operation.setting_name)
269 .await
270 .map_err(|e| OperationError::Internal(e.to_string()))?;
271
272 Ok(value)
273 }
274 .boxed()
275 }
276
277 pub fn repository_set_setting(
278 object: &Repository,
279 operation: SetSetting<AnySetting>,
280 state: DatabaseBackend,
281 ) -> BoxFuture<'static, Result<(), OperationError<SetSettingError>>> {
282 let object = object.clone();
283
284 async move {
285 let mut repository_backend = state.repository_backend.lock().await;
286 let value = repository_backend
287 .write_setting(&object, &operation.setting_name, &operation.value.0)
288 .await
289 .map_err(|e| OperationError::Internal(e.to_string()))?;
290
291 Ok(value)
292 }
293 .boxed()
294 }
295
296 pub fn instance_authentication_request(
297 object: &Instance,
298 operation: AuthenticationTokenRequest,
299 state: DatabaseBackend,
300 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
301 let object = object.clone();
302 async move {
303 let mut backend = state.user_backend.lock().await;
304
305 backend
306 .login(&object, operation)
307 .await
308 .map_err(|e| OperationError::Internal(e.to_string()))
309 }
310 .boxed()
311 }
312
313 pub fn instance_registration_request(
314 _object: &Instance,
315 operation: RegisterAccountRequest,
316 state: DatabaseBackend,
317 ) -> BoxFuture<'static, Result<UserAuthenticationToken, OperationError<InstanceError>>> {
318 async move {
319 let mut backend = state.user_backend.lock().await;
320
321 backend
322 .register(operation)
323 .await
324 .map_err(|e| OperationError::Internal(e.to_string()))
325 }
326 .boxed()
327 }
328