Can get single account information
This commit is contained in:
		| @@ -1,5 +1,6 @@ | |||||||
| use crate::controllers::HttpResult; | use crate::controllers::HttpResult; | ||||||
| use crate::controllers::server_controller::ServerConstraints; | use crate::controllers::server_controller::ServerConstraints; | ||||||
|  | use crate::extractors::account_extractor::AccountInPath; | ||||||
| use crate::extractors::auth_extractor::AuthExtractor; | use crate::extractors::auth_extractor::AuthExtractor; | ||||||
| use crate::services::accounts_service; | use crate::services::accounts_service; | ||||||
| use crate::services::accounts_service::UpdateAccountQuery; | use crate::services::accounts_service::UpdateAccountQuery; | ||||||
| @@ -33,3 +34,8 @@ pub async fn create(auth: AuthExtractor, req: web::Json<CreateAccountRequest>) - | |||||||
| pub async fn get_list(auth: AuthExtractor) -> HttpResult { | pub async fn get_list(auth: AuthExtractor) -> HttpResult { | ||||||
|     Ok(HttpResponse::Ok().json(accounts_service::get_list_user(auth.user_id()).await?)) |     Ok(HttpResponse::Ok().json(accounts_service::get_list_user(auth.user_id()).await?)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Get a single account | ||||||
|  | pub async fn get_single(account: AccountInPath) -> HttpResult { | ||||||
|  |     Ok(HttpResponse::Ok().json(account.as_ref())) | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								moneymgr_backend/src/extractors/account_extractor.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								moneymgr_backend/src/extractors/account_extractor.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | use crate::extractors::auth_extractor::AuthExtractor; | ||||||
|  | use crate::models::accounts::{Account, AccountID}; | ||||||
|  | use crate::services::accounts_service; | ||||||
|  | use actix_web::dev::Payload; | ||||||
|  | use actix_web::{FromRequest, HttpRequest}; | ||||||
|  | use serde::Deserialize; | ||||||
|  |  | ||||||
|  | #[derive(Deserialize)] | ||||||
|  | struct AccountIdInPath { | ||||||
|  |     account_id: AccountID, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(thiserror::Error, Debug)] | ||||||
|  | enum AccountExtractorError { | ||||||
|  |     #[error("Current user does not own the account!")] | ||||||
|  |     UserDoesNotOwnAccount, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub struct AccountInPath(Account); | ||||||
|  |  | ||||||
|  | impl AccountInPath { | ||||||
|  |     pub async fn load_account_from_path( | ||||||
|  |         auth: &AuthExtractor, | ||||||
|  |         id: AccountID, | ||||||
|  |     ) -> anyhow::Result<Self> { | ||||||
|  |         let account = accounts_service::get_by_id(id).await?; | ||||||
|  |  | ||||||
|  |         if account.user_id() != auth.user_id() { | ||||||
|  |             return Err(AccountExtractorError::UserDoesNotOwnAccount.into()); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Ok(Self(account)) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl FromRequest for AccountInPath { | ||||||
|  |     type Error = actix_web::Error; | ||||||
|  |     type Future = futures_util::future::LocalBoxFuture<'static, Result<Self, Self::Error>>; | ||||||
|  |  | ||||||
|  |     fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future { | ||||||
|  |         let req = req.clone(); | ||||||
|  |         Box::pin(async move { | ||||||
|  |             let auth = AuthExtractor::extract(&req).await?; | ||||||
|  |  | ||||||
|  |             let account_id = | ||||||
|  |                 actix_web::web::Path::<AccountIdInPath>::from_request(&req, &mut Payload::None) | ||||||
|  |                     .await? | ||||||
|  |                     .account_id; | ||||||
|  |  | ||||||
|  |             Self::load_account_from_path(&auth, account_id) | ||||||
|  |                 .await | ||||||
|  |                 .map_err(|e| { | ||||||
|  |                     log::error!("Failed to extract account ID from URL! {}", e); | ||||||
|  |                     actix_web::error::ErrorNotFound("Could not fetch account information!") | ||||||
|  |                 }) | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl AsRef<Account> for AccountInPath { | ||||||
|  |     fn as_ref(&self) -> &Account { | ||||||
|  |         &self.0 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,2 +1,3 @@ | |||||||
|  | pub mod account_extractor; | ||||||
| pub mod auth_extractor; | pub mod auth_extractor; | ||||||
| pub mod money_session; | pub mod money_session; | ||||||
|   | |||||||
| @@ -91,25 +91,26 @@ async fn main() -> std::io::Result<()> { | |||||||
|                 web::get().to(auth_controller::sign_out), |                 web::get().to(auth_controller::sign_out), | ||||||
|             ) |             ) | ||||||
|             // Tokens controller |             // Tokens controller | ||||||
|             .route("/api/tokens", web::post().to(tokens_controller::create)) |             .route("/api/token", web::post().to(tokens_controller::create)) | ||||||
|  |             .route("/api/tokens", web::get().to(tokens_controller::get_list)) | ||||||
|             .route( |             .route( | ||||||
|                 "/api/tokens/list", |                 "/api/token/{id}", | ||||||
|                 web::get().to(tokens_controller::get_list), |  | ||||||
|             ) |  | ||||||
|             .route( |  | ||||||
|                 "/api/tokens/{id}", |  | ||||||
|                 web::delete().to(tokens_controller::delete), |                 web::delete().to(tokens_controller::delete), | ||||||
|             ) |             ) | ||||||
|             // Accounts controller |             // Accounts controller | ||||||
|             .route("/api/accounts", web::post().to(accounts_controller::create)) |             .route("/api/account", web::post().to(accounts_controller::create)) | ||||||
|             .route( |             .route( | ||||||
|                 "/api/accounts/list", |                 "/api/accounts", | ||||||
|                 web::get().to(accounts_controller::get_list), |                 web::get().to(accounts_controller::get_list), | ||||||
|             ) |             ) | ||||||
|  |             .route( | ||||||
|  |                 "/api/account/{account_id}", | ||||||
|  |                 web::get().to(accounts_controller::get_single), | ||||||
|  |             ) | ||||||
|             // TODO : update account |             // TODO : update account | ||||||
|             //TODO |             //TODO | ||||||
|             /*.route( |             /*.route( | ||||||
|                 "/api/accounts/{id}", |                 "/api/accounts/{account_id}", | ||||||
|                 web::delete().to(accounts_controller::delete), |                 web::delete().to(accounts_controller::delete), | ||||||
|             )*/ |             )*/ | ||||||
|             // TODO : set as default |             // TODO : set as default | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ export class TokensApi { | |||||||
|   static async GetList(): Promise<Token[]> { |   static async GetList(): Promise<Token[]> { | ||||||
|     return ( |     return ( | ||||||
|       await APIClient.exec({ |       await APIClient.exec({ | ||||||
|         uri: "/tokens/list", |         uri: "/tokens", | ||||||
|         method: "GET", |         method: "GET", | ||||||
|       }) |       }) | ||||||
|     ).data; |     ).data; | ||||||
| @@ -51,7 +51,7 @@ export class TokensApi { | |||||||
|   static async Create(t: NewToken): Promise<TokenWithSecret> { |   static async Create(t: NewToken): Promise<TokenWithSecret> { | ||||||
|     return ( |     return ( | ||||||
|       await APIClient.exec({ |       await APIClient.exec({ | ||||||
|         uri: "/tokens", |         uri: "/token", | ||||||
|         method: "POST", |         method: "POST", | ||||||
|         jsonData: t, |         jsonData: t, | ||||||
|       }) |       }) | ||||||
| @@ -63,7 +63,7 @@ export class TokensApi { | |||||||
|    */ |    */ | ||||||
|   static async Delete(t: Token): Promise<void> { |   static async Delete(t: Token): Promise<void> { | ||||||
|     await APIClient.exec({ |     await APIClient.exec({ | ||||||
|       uri: `/tokens/${t.id}`, |       uri: `/token/${t.id}`, | ||||||
|       method: "DELETE", |       method: "DELETE", | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user