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

ambee/giterated

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

Begin new protocol refactor

Amber - ⁨2⁩ years ago

parent: tbd commit: ⁨26651b1

⁨giterated-models/src/operation/instance.rs⁩ - ⁨5286⁩ bytes
Raw
1 use secrecy::Secret;
2 use serde::{Deserialize, Serialize};
3
4 use crate::{
5 error::InstanceError,
6 model::{
7 authenticated::UserAuthenticationToken,
8 instance::Instance,
9 repository::{Repository, RepositoryVisibility},
10 user::{Password, User},
11 },
12 };
13
14 use super::{GiteratedOperation, Object, ObjectBackend};
15
16 /// An account registration request.
17 ///
18 /// # Authentication
19 /// - Instance Authentication
20 /// - **ONLY ACCEPTED WHEN SAME-INSTANCE**
21 #[derive(Clone, Debug, Serialize, Deserialize)]
22 pub struct RegisterAccountRequest {
23 pub username: String,
24 pub email: Option<String>,
25 pub password: Secret<Password>,
26 }
27
28 impl GiteratedOperation<Instance> for RegisterAccountRequest {
29 type Success = UserAuthenticationToken;
30 type Failure = InstanceError;
31 }
32
33 #[derive(Clone, Debug, Serialize, Deserialize)]
34 pub struct RegisterAccountResponse {
35 pub token: String,
36 }
37
38 /// An authentication token request.
39 ///
40 /// AKA Login Request
41 ///
42 /// # Authentication
43 /// - Instance Authentication
44 /// - Identifies the Instance to issue the token for
45 /// # Authorization
46 /// - Credentials ([`crate::backend::AuthBackend`]-based)
47 /// - Identifies the User account to issue a token for
48 /// - Decrypts user private key to issue to
49 #[derive(Clone, Debug, Serialize, Deserialize)]
50 pub struct AuthenticationTokenRequest {
51 pub instance: Instance,
52 pub username: String,
53 pub password: Secret<Password>,
54 }
55
56 impl GiteratedOperation<Instance> for AuthenticationTokenRequest {
57 type Success = UserAuthenticationToken;
58 type Failure = InstanceError;
59 }
60
61 /// An authentication token extension request.
62 ///
63 /// # Authentication
64 /// - Instance Authentication
65 /// - Identifies the Instance to issue the token for
66 /// - User Authentication
67 /// - Authenticates the validity of the token
68 /// # Authorization
69 /// - Token-based
70 /// - Validates authorization using token's authenticity
71 #[derive(Clone, Debug, Serialize, Deserialize)]
72 pub struct TokenExtensionRequest {
73 pub token: UserAuthenticationToken,
74 }
75
76 impl GiteratedOperation<Instance> for TokenExtensionRequest {
77 type Success = Option<UserAuthenticationToken>;
78 type Failure = InstanceError;
79 }
80
81 /// A request to create a repository.
82 ///
83 /// # Authentication
84 /// - Instance Authentication
85 /// - Used to validate User token `issued_for`
86 /// - User Authentication
87 /// - Used to source owning user
88 /// - Used to authorize user token against user's instance
89 /// # Authorization
90 /// - Instance Authorization
91 /// - Used to authorize action using User token requiring a correct `issued_for` and valid issuance from user's instance
92 /// - User Authorization
93 /// - Potential User permissions checks
94 #[derive(Clone, Debug, Serialize, Deserialize)]
95 pub struct RepositoryCreateRequest {
96 pub instance: Option<Instance>,
97 pub name: String,
98 pub description: Option<String>,
99 pub visibility: RepositoryVisibility,
100 pub default_branch: String,
101 pub owner: User,
102 }
103
104 impl GiteratedOperation<Instance> for RepositoryCreateRequest {
105 type Success = Repository;
106 type Failure = InstanceError;
107 }
108
109 impl<B: ObjectBackend + std::fmt::Debug> Object<'_, Instance, B> {
110 pub async fn register_account(
111 &mut self,
112 email: Option<&str>,
113 username: &str,
114 password: &Secret<Password>,
115 ) -> Result<UserAuthenticationToken, InstanceError> {
116 self.request::<RegisterAccountRequest>(RegisterAccountRequest {
117 username: username.to_string(),
118 email: email.map(|s| s.to_string()),
119 password: password.clone(),
120 })
121 }
122
123 pub async fn authentication_token(
124 &mut self,
125 username: &str,
126 password: &Secret<Password>,
127 ) -> Result<UserAuthenticationToken, InstanceError> {
128 self.request::<AuthenticationTokenRequest>(AuthenticationTokenRequest {
129 instance: self.inner.clone(),
130 username: username.to_string(),
131 password: password.clone(),
132 })
133 }
134
135 pub async fn authentication_token_for(
136 &mut self,
137 instance: &Instance,
138 username: &str,
139 password: &Secret<Password>,
140 ) -> Result<UserAuthenticationToken, InstanceError> {
141 self.request::<AuthenticationTokenRequest>(AuthenticationTokenRequest {
142 instance: instance.clone(),
143 username: username.to_string(),
144 password: password.clone(),
145 })
146 }
147
148 pub async fn token_extension(
149 &mut self,
150 token: &UserAuthenticationToken,
151 ) -> Result<Option<UserAuthenticationToken>, InstanceError> {
152 self.request::<TokenExtensionRequest>(TokenExtensionRequest {
153 token: token.clone(),
154 })
155 }
156
157 pub async fn create_repository(
158 &mut self,
159 instance: &Instance,
160 name: &str,
161 visibility: RepositoryVisibility,
162 default_branch: &str,
163 owner: &User,
164 ) -> Result<Repository, InstanceError> {
165 self.request::<RepositoryCreateRequest>(RepositoryCreateRequest {
166 instance: Some(instance.clone()),
167 name: name.to_string(),
168 description: None,
169 visibility,
170 default_branch: default_branch.to_string(),
171 owner: owner.clone(),
172 })
173 }
174 }
175