diff --git a/src/api_data/current_user_id.rs b/src/api_data/current_user_id.rs new file mode 100644 index 0000000..ca512a9 --- /dev/null +++ b/src/api_data/current_user_id.rs @@ -0,0 +1,18 @@ +use serde::{Deserialize, Serialize}; + +use crate::data::user::UserID; + +/// Current user ID +#[derive(Serialize, Deserialize)] +#[allow(non_snake_case)] +pub struct CurrentUserID { + userID: i64 +} + +impl CurrentUserID { + pub fn new(id: UserID) -> CurrentUserID { + CurrentUserID { + userID: id + } + } +} \ No newline at end of file diff --git a/src/api_data/mod.rs b/src/api_data/mod.rs index efa7b61..ef959e4 100644 --- a/src/api_data/mod.rs +++ b/src/api_data/mod.rs @@ -8,4 +8,5 @@ //! Pierre Hubert pub mod http_error; -pub mod login_success; \ No newline at end of file +pub mod login_success; +pub mod current_user_id; \ No newline at end of file diff --git a/src/controllers/account_controller.rs b/src/controllers/account_controller.rs index 42bf5b2..9ee1a40 100644 --- a/src/controllers/account_controller.rs +++ b/src/controllers/account_controller.rs @@ -2,6 +2,7 @@ use crate::api_data::login_success::LoginSuccess; use crate::controllers::routes::RequestResult; use crate::data::http_request_handler::HttpRequestHandler; use crate::helpers::account_helper; +use crate::api_data::current_user_id::CurrentUserID; /// Account controller /// @@ -28,4 +29,9 @@ pub fn login_user(request: &mut HttpRequestHandler) -> RequestResult { request.forbidden("Invalid email address / password!".to_string()) } } +} + +/// Get current user ID +pub fn user_id(request: &mut HttpRequestHandler) -> RequestResult { + request.set_response(CurrentUserID::new(request.user_id()?)) } \ No newline at end of file diff --git a/src/controllers/routes.rs b/src/controllers/routes.rs index c839b74..faaac43 100644 --- a/src/controllers/routes.rs +++ b/src/controllers/routes.rs @@ -51,6 +51,15 @@ impl Route { func } } + + pub fn post(uri: &'static str, func: RequestProcess) -> Route { + Route { + method: POST, + need_login: true, + uri, + func + } + } } /// Get the list of routes available @@ -62,5 +71,8 @@ pub fn get_routes() -> Vec { // Account controller Route::post_without_login("/account/login", Box::new(account_controller::login_user)), Route::post_without_login("/user/connectUSER", Box::new(account_controller::login_user)), + + Route::post("/account/id", Box::new(account_controller::user_id)), + Route::post("/user/getCurrentUserID", Box::new(account_controller::user_id)), ] } \ No newline at end of file diff --git a/src/controllers/server.rs b/src/controllers/server.rs index dedf696..37a4c64 100644 --- a/src/controllers/server.rs +++ b/src/controllers/server.rs @@ -108,6 +108,11 @@ fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> RequestR // Validate client token req.check_client_token()?; + // Check user token, if required + if route.need_login || req.has_post_parameter("userToken1") { + req.check_user_token()?; + } + (route.func)(req) } diff --git a/src/data/http_request_handler.rs b/src/data/http_request_handler.rs index 14ab0d4..139be4f 100644 --- a/src/data/http_request_handler.rs +++ b/src/data/http_request_handler.rs @@ -4,12 +4,13 @@ use std::error::Error; use serde::Serialize; use crate::data::error::{ResultBoxError, ExecError}; use std::collections::HashMap; -use crate::helpers::api_helper; +use crate::helpers::{api_helper, account_helper}; use actix_web::http::{HeaderName, HeaderValue}; use std::str::FromStr; use crate::data::config::conf; use crate::data::api_client::APIClient; use crate::api_data::http_error::HttpError; +use crate::data::user::UserID; /// Http request handler /// @@ -40,6 +41,7 @@ pub struct HttpRequestHandler { response: Option, headers: HashMap, client: Option, + curr_user_id: Option, } impl HttpRequestHandler { @@ -51,6 +53,7 @@ impl HttpRequestHandler { response: None, headers: HashMap::new(), client: None, + curr_user_id: None, } } @@ -175,8 +178,8 @@ impl HttpRequestHandler { } } - /// Check login tokens - pub fn check_client_token(&mut self) -> Result<(), Box> { + /// Check API client tokens + pub fn check_client_token(&mut self) -> RequestResult { let api_name = self.post_string("serviceName")?; let api_token = self.post_string("serviceToken")?; @@ -209,6 +212,28 @@ impl HttpRequestHandler { Ok(()) } + /// Check login token + pub fn check_user_token(&mut self) -> RequestResult { + let token = self.post_string("userToken1")?; + + // Find user + let user_id = self.ok_or_bad_request( + account_helper::get_user_by_login_token(&token, self.api_client()), + "Please check your login tokens!")?; + + self.curr_user_id = Some(user_id); + + Ok(()) + } + + /// Get user ID. This function assess that a user ID is available to continue + pub fn user_id(&self) -> ResultBoxError { + match self.curr_user_id { + Some(s) => Ok(s), + None => Err(ExecError::boxed_new("Could not get required user ID!")) + } + } + /// Get an email included in the request pub fn post_email(&mut self, name: &str) -> ResultBoxError { let mail = self.post_string(name)?; diff --git a/src/helpers/account_helper.rs b/src/helpers/account_helper.rs index 8fa6578..968ca2e 100644 --- a/src/helpers/account_helper.rs +++ b/src/helpers/account_helper.rs @@ -34,7 +34,7 @@ pub fn login_user(email: &str, password: &str, client: &APIClient) -> ResultBoxE let new_token = UserAccessToken { user_id: user.id, client_id: client.id, - token: rand_str(150) + token: rand_str(150), }; // Save it @@ -63,4 +63,14 @@ fn get_client_tokens(user_id: UserID, client: &APIClient) -> ResultBoxError ResultBoxError { + database::query_row( + QueryInfo::new(USER_ACCESS_TOKENS_TABLE) + .cond_u32("service_id", client.id) + .cond("token1", token), + |res| res.get_int64("user_id"), + ) } \ No newline at end of file