use secrecy::Secret; use serde::{Deserialize, Serialize}; use crate::{ error::InstanceError, model::{ authenticated::UserAuthenticationToken, instance::Instance, repository::{Repository, RepositoryVisibility}, user::{Password, User}, }, }; use super::{GiteratedOperation, Object, ObjectBackend}; /// An account registration request. /// /// # Authentication /// - Instance Authentication /// - **ONLY ACCEPTED WHEN SAME-INSTANCE** #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RegisterAccountRequest { pub username: String, pub email: Option, pub password: Secret, } impl GiteratedOperation for RegisterAccountRequest { type Success = UserAuthenticationToken; type Failure = InstanceError; } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RegisterAccountResponse { pub token: String, } /// An authentication token request. /// /// AKA Login Request /// /// # Authentication /// - Instance Authentication /// - Identifies the Instance to issue the token for /// # Authorization /// - Credentials ([`crate::backend::AuthBackend`]-based) /// - Identifies the User account to issue a token for /// - Decrypts user private key to issue to #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AuthenticationTokenRequest { pub instance: Instance, pub username: String, pub password: Secret, } impl GiteratedOperation for AuthenticationTokenRequest { type Success = UserAuthenticationToken; type Failure = InstanceError; } /// An authentication token extension request. /// /// # Authentication /// - Instance Authentication /// - Identifies the Instance to issue the token for /// - User Authentication /// - Authenticates the validity of the token /// # Authorization /// - Token-based /// - Validates authorization using token's authenticity #[derive(Clone, Debug, Serialize, Deserialize)] pub struct TokenExtensionRequest { pub token: UserAuthenticationToken, } impl GiteratedOperation for TokenExtensionRequest { type Success = Option; type Failure = InstanceError; } /// A request to create a repository. /// /// # Authentication /// - Instance Authentication /// - Used to validate User token `issued_for` /// - User Authentication /// - Used to source owning user /// - Used to authorize user token against user's instance /// # Authorization /// - Instance Authorization /// - Used to authorize action using User token requiring a correct `issued_for` and valid issuance from user's instance /// - User Authorization /// - Potential User permissions checks #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RepositoryCreateRequest { pub instance: Option, pub name: String, pub description: Option, pub visibility: RepositoryVisibility, pub default_branch: String, pub owner: User, } impl GiteratedOperation for RepositoryCreateRequest { type Success = Repository; type Failure = InstanceError; } impl Object<'_, Instance, B> { pub async fn register_account( &mut self, email: Option<&str>, username: &str, password: &Secret, ) -> Result { self.request::(RegisterAccountRequest { username: username.to_string(), email: email.map(|s| s.to_string()), password: password.clone(), }) } pub async fn authentication_token( &mut self, username: &str, password: &Secret, ) -> Result { self.request::(AuthenticationTokenRequest { instance: self.inner.clone(), username: username.to_string(), password: password.clone(), }) } pub async fn authentication_token_for( &mut self, instance: &Instance, username: &str, password: &Secret, ) -> Result { self.request::(AuthenticationTokenRequest { instance: instance.clone(), username: username.to_string(), password: password.clone(), }) } pub async fn token_extension( &mut self, token: &UserAuthenticationToken, ) -> Result, InstanceError> { self.request::(TokenExtensionRequest { token: token.clone(), }) } pub async fn create_repository( &mut self, instance: &Instance, name: &str, visibility: RepositoryVisibility, default_branch: &str, owner: &User, ) -> Result { self.request::(RepositoryCreateRequest { instance: Some(instance.clone()), name: name.to_string(), description: None, visibility, default_branch: default_branch.to_string(), owner: owner.clone(), }) } }