use std::error::Error; use crate::constants::admin::AdminRole; use crate::controllers::*; use crate::controllers::admin::*; use crate::data::http_request_handler::HttpRequestHandler; use crate::routes::Method::{GET, POST}; /// Project routes /// /// @author Pierre Hubert #[derive(PartialEq)] pub enum Method { GET, 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), } /// Scope of the route pub enum RouteScope { // Route accessible by a "normal" user of Comunic USER, // Route accessible by an administrator of Comunic ADMIN, } impl LimitPolicy { pub fn is_none(&self) -> bool { matches!(self, LimitPolicy::NONE) } pub fn get_count(&self) -> u64 { match self { LimitPolicy::NONE => 0, LimitPolicy::SUCCESS(n) => *n, LimitPolicy::FAILURE(n) => *n, LimitPolicy::ANY(n) => *n, } } } /// Define types pub type RequestResult = Result<(), Box>; pub type RequestProcess = Box RequestResult>; pub struct Route { /// Route scope pub scope: RouteScope, /// The Verb used for the request pub method: Method, /// The URI of the request, with the leading "/" pub uri: &'static str, /// If set to true, unauthenticated requests will be rejected pub need_login: bool, /// Request rate policy pub limit_policy: LimitPolicy, /// Administrator role required to use the route pub admin_role: Option, } impl Route { pub fn get_without_login(uri: &'static str) -> Route { Route { scope: RouteScope::USER, method: GET, need_login: false, uri, limit_policy: LimitPolicy::NONE, admin_role: None, } } pub fn post_without_login(uri: &'static str) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: false, uri, limit_policy: LimitPolicy::NONE, admin_role: None, } } pub fn limited_post_without_login(uri: &'static str, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: false, uri, limit_policy, admin_role: None, } } pub fn post(uri: &'static str) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: true, uri, limit_policy: LimitPolicy::NONE, admin_role: None, } } pub fn limited_post(uri: &'static str, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::USER, method: POST, need_login: true, uri, limit_policy, admin_role: None, } } pub fn limited_admin_post_without_login(uri: &'static str, limit_policy: LimitPolicy) -> Route { Route { scope: RouteScope::ADMIN, method: POST, need_login: false, uri, limit_policy, admin_role: None, } } pub fn admin_post(uri: &'static str) -> Route { Route { scope: RouteScope::ADMIN, method: POST, need_login: true, uri, limit_policy: LimitPolicy::NONE, admin_role: None, } } pub fn admin_post_restricted(uri: &'static str, role: AdminRole) -> Route { Route { scope: RouteScope::ADMIN, method: POST, need_login: true, uri, limit_policy: LimitPolicy::NONE, admin_role: Some(role), } } } macro_rules! route { ($req_uri: expr, $call: expr, GET_NO_LOGIN, $uri: expr, $func: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::get_without_login($uri)), None) } }; ($req_uri: expr, $call: expr, POST_NO_LOGIN, $uri: expr, $func: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::post_without_login($uri)), None) } }; ($req_uri: expr, $call: expr, POST_LOGIN, $uri: expr, $func: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::post($uri)), None) } }; ($req_uri: expr, $call: expr, LTD_POST_NO_LOGIN, $uri: expr, $func: expr, $policy: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::limited_post_without_login($uri, $policy)), None) } }; ($req_uri: expr, $call: expr, LTD_POST_LOGIN, $uri: expr, $func: expr, $policy: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::limited_post($uri, $policy)), None) } }; ($req_uri: expr, $call: expr, LTD_ADMIN_POST_NO_LOGIN, $uri: expr, $func: expr, $policy: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::limited_admin_post_without_login($uri, $policy)), None) } }; ($req_uri: expr, $call: expr, ADMIN_POST_LOGIN, $uri: expr, $func: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::admin_post($uri)), None); } }; ($req_uri: expr, $call: expr, ADMIN_POST_LOGIN_RESTR, $uri: expr, $func: expr, $role: expr)=>{ if($uri.eq($req_uri)) { if let Some(c) = $call { return (None, Some($func(c).await)); } return (Some(Route::admin_post_restricted($uri, $role)), None); } }; } pub async fn find_route(req_uri: &str, call: Option<&mut HttpRequestHandler>) -> (Option, Option) { // Server meta routes route!(req_uri, call, GET_NO_LOGIN, "/", server_controller::main_index); route!(req_uri, call, POST_NO_LOGIN, "/server/config", server_controller::get_config); // Main user WebSocket route!(req_uri, call, POST_LOGIN, "/ws/token", user_ws_controller::get_token); // Account controller route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/create", account_controller::create, LimitPolicy::SUCCESS(10)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/login", account_controller::login_user, LimitPolicy::FAILURE(10)); route!(req_uri, call, POST_LOGIN, "/account/logout", account_controller::logout_user); route!(req_uri, call, POST_LOGIN, "/account/disconnect_all_devices", account_controller::disconnect_all_devices); route!(req_uri, call, POST_LOGIN, "/account/id", account_controller::user_id); route!(req_uri, call, POST_LOGIN, "/account/mail", account_controller::get_mail); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/exists_email", account_controller::exists_mail, LimitPolicy::ANY(30)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/has_security_questions", account_controller::has_security_questions, LimitPolicy::FAILURE(10)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/get_security_questions", account_controller::get_security_questions, LimitPolicy::FAILURE(10)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/check_security_answers", account_controller::check_security_answers, LimitPolicy::FAILURE(10)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/check_password_reset_token", account_controller::check_password_reset_token, LimitPolicy::FAILURE(10)); route!(req_uri, call, LTD_POST_NO_LOGIN, "/account/reset_user_passwd", account_controller::reset_user_password, LimitPolicy::FAILURE(10)); route!(req_uri, call, LTD_POST_LOGIN, "/account/export_data", account_controller::export_data, LimitPolicy::ANY(10)); route!(req_uri, call, POST_LOGIN, "/account/delete", account_controller::delete_account); // User controller route!(req_uri, call, POST_LOGIN, "/user/getInfo", user_controller::get_single); route!(req_uri, call, POST_LOGIN, "/user/getInfos", user_controller::get_single); route!(req_uri, call, POST_LOGIN, "/user/getInfoMultiple", user_controller::get_multiple); route!(req_uri, call, POST_LOGIN, "/user/getInfosMultiple", user_controller::get_multiple); route!(req_uri, call, POST_LOGIN, "/user/getAdvancedUserInfo", user_controller::get_advanced_info); route!(req_uri, call, POST_LOGIN, "/user/getAdvancedUserInfos", user_controller::get_advanced_info); // Settings controller route!(req_uri, call, POST_LOGIN, "/settings/get_general", settings_controller::get_general); route!(req_uri, call, POST_LOGIN, "/settings/set_general", settings_controller::set_general); route!(req_uri, call, POST_LOGIN, "/settings/check_user_directory_availability", settings_controller::check_virtual_directory); route!(req_uri, call, POST_LOGIN, "/settings/get_language", settings_controller::get_language); route!(req_uri, call, POST_LOGIN, "/settings/set_language", settings_controller::set_language); route!(req_uri, call, POST_LOGIN, "/settings/get_security", settings_controller::get_security); route!(req_uri, call, POST_LOGIN, "/settings/set_security", settings_controller::set_security); route!(req_uri, call, POST_LOGIN, "/settings/check_password", settings_controller::check_password); route!(req_uri, call, POST_LOGIN, "/settings/update_password", settings_controller::update_password); route!(req_uri, call, POST_LOGIN, "/settings/get_account_image", settings_controller::get_account_image_settings); route!(req_uri, call, POST_LOGIN, "/settings/upload_account_image", settings_controller::upload_account_image); route!(req_uri, call, POST_LOGIN, "/settings/delete_account_image", settings_controller::delete_account_image); route!(req_uri, call, POST_LOGIN, "/settings/set_account_image_visibility", settings_controller::set_account_image_visibility); route!(req_uri, call, POST_LOGIN, "/settings/upload_custom_emoji", settings_controller::upload_custom_emoji); route!(req_uri, call, POST_LOGIN, "/settings/delete_custom_emoji", settings_controller::delete_custom_emoji); route!(req_uri, call, POST_LOGIN, "/settings/get_data_conservation_policy", settings_controller::get_data_conservation_policy); route!(req_uri, call, LTD_POST_LOGIN, "/settings/set_data_conservation_policy", settings_controller::set_data_conservation_policy, LimitPolicy::FAILURE(10)); route!(req_uri, call, POST_LOGIN, "/settings/get_notifications", settings_controller::get_notifications); route!(req_uri, call, POST_LOGIN, "/settings/set_notifications", settings_controller::set_notifications); // Push notifications controller route!(req_uri, call, POST_LOGIN, "/push_notifications/status", push_notifications_controller::get_status); route!(req_uri, call, POST_LOGIN, "/push_notifications/configure", push_notifications_controller::configure); // Friends controller route!(req_uri, call, POST_LOGIN, "/friends/getList", friends_controller::get_list); route!(req_uri, call, POST_LOGIN, "/friends/get_single_infos", friends_controller::get_single_friendship_info); route!(req_uri, call, POST_LOGIN, "/friends/get_user_list", friends_controller::get_other_user_list); route!(req_uri, call, POST_LOGIN, "/friends/getStatus", friends_controller::get_status); route!(req_uri, call, POST_LOGIN, "/friends/sendRequest", friends_controller::send_request); route!(req_uri, call, POST_LOGIN, "/friends/removeRequest", friends_controller::cancel_request); route!(req_uri, call, POST_LOGIN, "/friends/respondRequest", friends_controller::respond_request); route!(req_uri, call, POST_LOGIN, "/friends/remove", friends_controller::remove_friend); route!(req_uri, call, POST_LOGIN, "/friends/setFollowing", friends_controller::set_following); route!(req_uri, call, POST_LOGIN, "/friends/set_can_post_texts", friends_controller::set_can_post_texts); // Conversations controller route!(req_uri, call, POST_LOGIN, "/conversations/create", conversations_controller::create); route!(req_uri, call, POST_LOGIN, "/conversations/getList", conversations_controller::get_list); route!(req_uri, call, POST_LOGIN, "/conversations/get_single", conversations_controller::get_single); route!(req_uri, call, POST_LOGIN, "/conversations/updateSettings", conversations_controller::update_settings); route!(req_uri, call, POST_LOGIN, "/conversations/change_image", conversations_controller::change_image); route!(req_uri, call, POST_LOGIN, "/conversations/delete_image", conversations_controller::delete_image); route!(req_uri, call, POST_LOGIN, "/conversations/addMember", conversations_controller::add_member); route!(req_uri, call, POST_LOGIN, "/conversations/setAdmin", conversations_controller::set_admin); route!(req_uri, call, POST_LOGIN, "/conversations/removeMember", conversations_controller::remove_member); route!(req_uri, call, POST_LOGIN, "/conversations/getPrivate", conversations_controller::find_private); route!(req_uri, call, POST_LOGIN, "/conversations/refresh_single", conversations_controller::refresh_single); route!(req_uri, call, POST_LOGIN, "/conversations/get_older_messages", conversations_controller::get_older_messages); route!(req_uri, call, POST_LOGIN, "/conversations/sendMessage", conversations_controller::send_message); route!(req_uri, call, POST_LOGIN, "/conversations/get_number_unread", conversations_controller::count_unread); route!(req_uri, call, POST_LOGIN, "/conversations/get_list_unread", conversations_controller::list_unread); route!(req_uri, call, POST_LOGIN, "/conversations/delete", conversations_controller::delete_conversation); route!(req_uri, call, POST_LOGIN, "/conversations/updateMessage", conversations_controller::update_message); route!(req_uri, call, POST_LOGIN, "/conversations/deleteMessage", conversations_controller::delete_message); // Search controller route!(req_uri, call, POST_LOGIN, "/search/user", search_controller::search_user); route!(req_uri, call, POST_LOGIN, "/user/search", search_controller::search_user); route!(req_uri, call, POST_LOGIN, "/search/global", search_controller::search_global); // Groups controller route!(req_uri, call, POST_LOGIN, "/groups/create", groups_controller::create); route!(req_uri, call, POST_LOGIN, "/groups/get_my_list", groups_controller::get_list_user); route!(req_uri, call, POST_LOGIN, "/groups/get_info", groups_controller::get_info_single); route!(req_uri, call, POST_LOGIN, "/groups/get_multiple_info", groups_controller::get_info_multiple); route!(req_uri, call, POST_LOGIN, "/groups/get_advanced_info", groups_controller::get_advanced_info); route!(req_uri, call, POST_LOGIN, "/groups/get_settings", groups_controller::get_settings); route!(req_uri, call, POST_LOGIN, "/groups/set_settings", groups_controller::set_settings); route!(req_uri, call, POST_LOGIN, "/groups/checkVirtualDirectory", groups_controller::check_virtual_dir); route!(req_uri, call, POST_LOGIN, "/groups/upload_logo", groups_controller::upload_logo); route!(req_uri, call, POST_LOGIN, "/groups/delete_logo", groups_controller::delete_logo); route!(req_uri, call, POST_LOGIN, "/groups/create_conversation", groups_controller::create_conversation); route!(req_uri, call, POST_LOGIN, "/groups/set_conversation_visibility", groups_controller::set_conversation_visibility); route!(req_uri, call, POST_LOGIN, "/groups/delete_conversation", groups_controller::delete_conversation); route!(req_uri, call, POST_LOGIN, "/groups/get_members", groups_controller::get_members); route!(req_uri, call, POST_LOGIN, "/groups/invite", groups_controller::invite_user); route!(req_uri, call, POST_LOGIN, "/groups/cancel_invitation", groups_controller::cancel_invitation); route!(req_uri, call, POST_LOGIN, "/groups/respond_invitation", groups_controller::respond_invitation); route!(req_uri, call, POST_LOGIN, "/groups/send_request", groups_controller::send_request); route!(req_uri, call, POST_LOGIN, "/groups/cancel_request", groups_controller::cancel_request); route!(req_uri, call, POST_LOGIN, "/groups/delete_member", groups_controller::delete_member); route!(req_uri, call, POST_LOGIN, "/groups/update_membership_level", groups_controller::update_membership); route!(req_uri, call, POST_LOGIN, "/groups/respond_request", groups_controller::respond_request); route!(req_uri, call, POST_LOGIN, "/groups/get_membership", groups_controller::get_membership); route!(req_uri, call, POST_LOGIN, "/groups/remove_membership", groups_controller::remove_membership); route!(req_uri, call, POST_LOGIN, "/groups/set_following", groups_controller::set_following); route!(req_uri, call, LTD_POST_LOGIN, "/groups/delete", groups_controller::delete_group, LimitPolicy::FAILURE(10)); // Posts controller route!(req_uri, call, POST_LOGIN, "/posts/get_user", posts_controller::get_list_user); route!(req_uri, call, POST_LOGIN, "/posts/get_group", posts_controller::get_list_group); route!(req_uri, call, POST_LOGIN, "/posts/get_latest", posts_controller::get_latest); route!(req_uri, call, POST_LOGIN, "/posts/get_single", posts_controller::get_single); route!(req_uri, call, POST_LOGIN, "/posts/create", posts_controller::create_post); route!(req_uri, call, POST_LOGIN, "/posts/set_visibility_level", posts_controller::set_visibility_level); route!(req_uri, call, POST_LOGIN, "/posts/update_content", posts_controller::update_content); route!(req_uri, call, POST_LOGIN, "/posts/delete", posts_controller::delete); route!(req_uri, call, POST_LOGIN, "/posts/getAvailableTargets", posts_controller::get_targets); // Comments controller route!(req_uri, call, POST_LOGIN, "/comments/create", comments_controller::create); route!(req_uri, call, POST_LOGIN, "/comments/get_single", comments_controller::get_single); route!(req_uri, call, POST_LOGIN, "/comments/edit", comments_controller::edit); route!(req_uri, call, POST_LOGIN, "/comments/delete", comments_controller::delete); // Likes controller route!(req_uri, call, POST_LOGIN, "/likes/update", likes_controller::update); // Surveys controller route!(req_uri, call, POST_LOGIN, "/surveys/get_info", surveys_controller::get_info_single); route!(req_uri, call, POST_LOGIN, "/surveys/send_response", surveys_controller::send_response); route!(req_uri, call, POST_LOGIN, "/surveys/cancel_response", surveys_controller::cancel_response); route!(req_uri, call, POST_LOGIN, "/surveys/create_new_choice", surveys_controller::create_new_choice); route!(req_uri, call, POST_LOGIN, "/surveys/block_new_choices_creation", surveys_controller::block_new_choices_creation); // Notifications controller route!(req_uri, call, POST_LOGIN, "/notifications/count_unread", notifications_controller::count_unread); route!(req_uri, call, POST_LOGIN, "/notifications/count_all_news", notifications_controller::count_all_news); route!(req_uri, call, POST_LOGIN, "/notifications/get_list_unread", notifications_controller::get_list_unread); route!(req_uri, call, POST_LOGIN, "/notifications/mark_seen", notifications_controller::mark_seen); route!(req_uri, call, POST_LOGIN, "/notifications/delete_all", notifications_controller::delete_all); // Virtual directory controller route!(req_uri, call, POST_LOGIN, "/user/findbyfolder", virtual_directory_controller::find_user); route!(req_uri, call, POST_LOGIN, "/virtualDirectory/find", virtual_directory_controller::find); // Web application controller route!(req_uri, call, POST_LOGIN, "/webApp/getMemberships", web_app_controller::get_memberships); // Report controller route!(req_uri, call, LTD_POST_LOGIN, "/reports/create", report_controller::report, LimitPolicy::ANY(10)); // Forez controller route!(req_uri, call, POST_LOGIN, "/forez/get_groups", forez_controller::get_list_groups); route!(req_uri, call, POST_LOGIN, "/forez/get_member_info", forez_controller::get_member_info); // === ADMIN ROUTES === // Admin accounts controller route!(req_uri, call, LTD_ADMIN_POST_NO_LOGIN, "/admin/accounts/auth_options", admin_account_controller::get_auth_options, LimitPolicy::FAILURE(5)); route!(req_uri, call, LTD_ADMIN_POST_NO_LOGIN, "/admin/accounts/auth_with_reset_token", admin_account_controller::auth_with_reset_token, LimitPolicy::FAILURE(5)); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/sign_out", admin_account_controller::sign_out); route!(req_uri, call, ADMIN_POST_LOGIN_RESTR, "/admin/accounts/create", admin_account_controller::create, AdminRole::MANAGE_ADMINS); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/id", admin_account_controller::get_admin_id); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/list", admin_account_controller::get_list); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/info", admin_account_controller::get_admin_info); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/update_general_settings", admin_account_controller::update_general_settings); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/accounts/generate_reset_token", admin_account_controller::generate_reset_token); // Admin security keys controller route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/keys/list", admin_keys_controller::get_keys_list); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/keys/challenge_register_key", admin_keys_controller::challenge_register_key); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/keys/register_key", admin_keys_controller::register_key); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/keys/delete_auth_key", admin_keys_controller::delete_auth_key); route!(req_uri, call, LTD_ADMIN_POST_NO_LOGIN, "/admin/keys/challenge_auth_with_key", admin_keys_controller::challenge_auth_with_key, LimitPolicy::ANY(10)); route!(req_uri, call, LTD_ADMIN_POST_NO_LOGIN, "/admin/keys/auth_with_key", admin_keys_controller::auth_with_key, LimitPolicy::ANY(10)); // Admin roles controller route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/roles/list", admin_roles_controller::get_list); route!(req_uri, call, ADMIN_POST_LOGIN_RESTR, "/admin/roles/toggle", admin_roles_controller::toggle, AdminRole::MANAGE_ADMINS); // Admin logs controller route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/logs/list", admin_logs_controller::get_list); // Admin users management controller route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/users/search", admin_users_controller::search); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/users/info", admin_users_controller::get_single); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/users/change_email_address", admin_users_controller::change_email_address); route!(req_uri, call, ADMIN_POST_LOGIN, "/admin/users/create_password_reset_link", admin_users_controller::create_password_reset_link); (None, None) }