diff --git a/src/controllers/routes.rs b/src/controllers/routes.rs index 69ea1bf..1b2baaa 100644 --- a/src/controllers/routes.rs +++ b/src/controllers/routes.rs @@ -13,6 +13,27 @@ pub enum Method { POST, } +/// Limitation policy of a request for a given IP address +/// +/// All the limit are on a per-hour basis (the first request that triggers the limit is the one +/// that is recorded) +pub enum LimitPolicy { + // No limit is applied to the request + NONE, + + // An acceptable threshold of successful requests (= 200) is defined, then the requests are + // rejected (they are not even processed) + SUCCESS(u64), + + // An acceptable threshold of unsuccessful requests (!= 200) is defined, then the requests are + // rejected (they are not even processed) + FAILURE(u64), + + // An acceptable threshold of request (successful or unsuccessful) is defined then the requests + // are rejected (they are not even processed) + ANY(u64), +} + /// Define types pub type RequestResult = Result<(), Box>; pub type RequestProcess = Box RequestResult>; @@ -29,6 +50,9 @@ pub struct Route { /// The function called to process a request pub func: RequestProcess, + + /// Request rate policy + pub limit_policy: LimitPolicy, } impl Route { @@ -38,6 +62,7 @@ impl Route { need_login: false, uri, func, + limit_policy: LimitPolicy::NONE, } } @@ -47,6 +72,17 @@ impl Route { need_login: false, uri, func, + limit_policy: LimitPolicy::NONE, + } + } + + pub fn limited_post_without_login(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route { + Route { + method: POST, + need_login: false, + uri, + func, + limit_policy, } } @@ -56,6 +92,17 @@ impl Route { need_login: true, uri, func, + limit_policy: LimitPolicy::NONE, + } + } + + pub fn limited_post(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route { + Route { + method: POST, + need_login: true, + uri, + func, + limit_policy, } } } @@ -67,30 +114,30 @@ pub fn get_routes() -> Vec { Route::get_without_login("/", Box::new(server_controller::main_index)), // Account controller - Route::post_without_login("/account/create", Box::new(account_controller::create)), - 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::limited_post_without_login("/account/create", Box::new(account_controller::create), LimitPolicy::SUCCESS(10)), + Route::limited_post_without_login("/account/login", Box::new(account_controller::login_user), LimitPolicy::FAILURE(10)), + Route::limited_post_without_login("/user/connectUSER", Box::new(account_controller::login_user), LimitPolicy::FAILURE(10)), Route::post("/account/logout", Box::new(account_controller::logout_user)), Route::post("/user/disconnectUSER", Box::new(account_controller::logout_user)), Route::post("/account/disconnect_all_devices", Box::new(account_controller::disconnect_all_devices)), Route::post("/account/id", Box::new(account_controller::user_id)), Route::post("/user/getCurrentUserID", Box::new(account_controller::user_id)), - Route::post_without_login("/account/exists_email", Box::new(account_controller::exists_mail)), - Route::post_without_login("/account/has_security_questions", Box::new(account_controller::has_security_questions)), - Route::post_without_login("/account/get_security_questions", Box::new(account_controller::get_security_questions)), - Route::post_without_login("/account/check_security_answers", Box::new(account_controller::check_security_answers)), - Route::post_without_login("/account/check_password_reset_token", Box::new(account_controller::check_password_reset_token)), - Route::post_without_login("/account/reset_user_passwd", Box::new(account_controller::reset_user_password)), - Route::post("/account/export_data", Box::new(account_controller::export_data)), + Route::limited_post_without_login("/account/exists_email", Box::new(account_controller::exists_mail), LimitPolicy::ANY(30)), + Route::limited_post_without_login("/account/has_security_questions", Box::new(account_controller::has_security_questions), LimitPolicy::FAILURE(10)), + Route::limited_post_without_login("/account/get_security_questions", Box::new(account_controller::get_security_questions), LimitPolicy::FAILURE(10)), + Route::limited_post_without_login("/account/check_security_answers", Box::new(account_controller::check_security_answers), LimitPolicy::FAILURE(10)), + Route::limited_post_without_login("/account/check_password_reset_token", Box::new(account_controller::check_password_reset_token), LimitPolicy::FAILURE(10)), + Route::limited_post_without_login("/account/reset_user_passwd", Box::new(account_controller::reset_user_password), LimitPolicy::FAILURE(10)), + Route::limited_post("/account/export_data", Box::new(account_controller::export_data), LimitPolicy::ANY(10)), Route::post("/account/delete", Box::new(account_controller::delete_account)), // User controller - Route::post_without_login("/user/getInfo", Box::new(user_controller::get_single)), - Route::post_without_login("/user/getInfos", Box::new(user_controller::get_single)), - Route::post_without_login("/user/getInfoMultiple", Box::new(user_controller::get_multiple)), - Route::post_without_login("/user/getInfosMultiple", Box::new(user_controller::get_multiple)), - Route::post_without_login("/user/getAdvancedUserInfo", Box::new(user_controller::get_advanced_info)), - Route::post_without_login("/user/getAdvancedUserInfos", Box::new(user_controller::get_advanced_info)), + Route::post("/user/getInfo", Box::new(user_controller::get_single)), + Route::post("/user/getInfos", Box::new(user_controller::get_single)), + Route::post("/user/getInfoMultiple", Box::new(user_controller::get_multiple)), + Route::post("/user/getInfosMultiple", Box::new(user_controller::get_multiple)), + Route::post("/user/getAdvancedUserInfo", Box::new(user_controller::get_advanced_info)), + Route::post("/user/getAdvancedUserInfos", Box::new(user_controller::get_advanced_info)), // Settings controller Route::post("/settings/get_general", Box::new(settings_controller::get_general)),