mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 21:39:21 +00:00
Add support for admin routes
This commit is contained in:
parent
56539d3476
commit
ffe6d464d7
@ -70,6 +70,9 @@ rtc-relay:
|
||||
allow-video: true
|
||||
max-users-per-video-calls: 6
|
||||
|
||||
# Admin URL
|
||||
admin-url: https://console.communiquons.org
|
||||
|
||||
# List of #Forez groups
|
||||
#
|
||||
# This option allows to enable some extra features for these groups
|
||||
|
12
src/controllers/admin/admin_account_controller.rs
Normal file
12
src/controllers/admin/admin_account_controller.rs
Normal file
@ -0,0 +1,12 @@
|
||||
//! # Admin account controller
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::routes::RequestResult;
|
||||
use crate::data::base_request_handler::BaseRequestHandler;
|
||||
|
||||
/// Get admin auth options
|
||||
pub fn get_auth_options(r: &mut HttpRequestHandler) -> RequestResult {
|
||||
r.ok()
|
||||
}
|
5
src/controllers/admin/mod.rs
Normal file
5
src/controllers/admin/mod.rs
Normal file
@ -0,0 +1,5 @@
|
||||
//! # Admin controllers
|
||||
//!
|
||||
//! @author Pierre Hubert
|
||||
|
||||
pub mod admin_account_controller;
|
@ -1,3 +1,5 @@
|
||||
pub mod admin;
|
||||
|
||||
pub mod server_controller;
|
||||
pub mod user_ws_controller;
|
||||
pub mod rtc_relay_controller;
|
||||
|
@ -51,6 +51,7 @@ pub struct Config {
|
||||
pub independent_push_service: Option<IndependentPushService>,
|
||||
pub database: DatabaseConfig,
|
||||
pub rtc_relay: Option<RtcRelayConfig>,
|
||||
pub admin_url: String,
|
||||
pub forez_groups: Vec<GroupID>,
|
||||
}
|
||||
|
||||
@ -152,6 +153,8 @@ impl Config {
|
||||
|
||||
rtc_relay: rtc_config,
|
||||
|
||||
admin_url: Self::yaml_str(parsed, "admin-url"),
|
||||
|
||||
forez_groups: parsed["forez_groups"]
|
||||
.as_vec()
|
||||
.unwrap_or(&vec![])
|
||||
|
@ -129,6 +129,17 @@ impl HttpRequestHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check admin origin
|
||||
pub fn check_admin_origin(&mut self) -> Res {
|
||||
if let Some(header) = self.request.headers().get("Origin") {
|
||||
if header.to_str()?.eq(&conf().admin_url) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
self.bad_request("Invalid origin for admin requests!".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseRequestHandler for HttpRequestHandler {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::error::Error;
|
||||
|
||||
use crate::controllers::{account_controller, comments_controller, conversations_controller, forez_controller, friends_controller, groups_controller, likes_controller, notifications_controller, posts_controller, push_notifications_controller, search_controller, server_controller, settings_controller, surveys_controller, user_controller, user_ws_controller, virtual_directory_controller, web_app_controller};
|
||||
use crate::controllers::admin::*;
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::routes::Method::{GET, POST};
|
||||
|
||||
@ -34,6 +35,15 @@ pub enum LimitPolicy {
|
||||
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)
|
||||
@ -54,6 +64,9 @@ pub type RequestResult = Result<(), Box<dyn Error>>;
|
||||
pub type RequestProcess = Box<dyn Fn(&mut HttpRequestHandler) -> RequestResult>;
|
||||
|
||||
pub struct Route {
|
||||
/// Route scope
|
||||
pub scope: RouteScope,
|
||||
|
||||
/// The Verb used for the request
|
||||
pub method: Method,
|
||||
|
||||
@ -73,6 +86,7 @@ pub struct Route {
|
||||
impl Route {
|
||||
pub fn get_without_login(uri: &'static str, func: RequestProcess) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::USER,
|
||||
method: GET,
|
||||
need_login: false,
|
||||
uri,
|
||||
@ -83,6 +97,7 @@ impl Route {
|
||||
|
||||
pub fn post_without_login(uri: &'static str, func: RequestProcess) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::USER,
|
||||
method: POST,
|
||||
need_login: false,
|
||||
uri,
|
||||
@ -93,6 +108,7 @@ impl Route {
|
||||
|
||||
pub fn limited_post_without_login(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::USER,
|
||||
method: POST,
|
||||
need_login: false,
|
||||
uri,
|
||||
@ -103,6 +119,7 @@ impl Route {
|
||||
|
||||
pub fn post(uri: &'static str, func: RequestProcess) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::USER,
|
||||
method: POST,
|
||||
need_login: true,
|
||||
uri,
|
||||
@ -113,6 +130,7 @@ impl Route {
|
||||
|
||||
pub fn limited_post(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::USER,
|
||||
method: POST,
|
||||
need_login: true,
|
||||
uri,
|
||||
@ -120,6 +138,17 @@ impl Route {
|
||||
limit_policy,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn limited_admin_post_without_login(uri: &'static str, func: RequestProcess, limit_policy: LimitPolicy) -> Route {
|
||||
Route {
|
||||
scope: RouteScope::ADMIN,
|
||||
method: POST,
|
||||
need_login: false,
|
||||
uri,
|
||||
func,
|
||||
limit_policy,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the list of routes available
|
||||
@ -301,5 +330,12 @@ pub fn get_routes() -> Vec<Route> {
|
||||
// Forez controller
|
||||
Route::post("/forez/get_groups", Box::new(forez_controller::get_list_groups)),
|
||||
Route::post("/forez/get_member_info", Box::new(forez_controller::get_member_info)),
|
||||
|
||||
|
||||
// === ADMIN ROUTES ===
|
||||
|
||||
|
||||
// Admin accounts controller
|
||||
Route::limited_admin_post_without_login("/admin/accounts/auth_options", Box::new(admin_account_controller::get_auth_options), LimitPolicy::FAILURE(5)),
|
||||
]
|
||||
}
|
@ -18,7 +18,7 @@ use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestVal
|
||||
use crate::data::config::Config;
|
||||
use crate::data::http_request_handler::HttpRequestHandler;
|
||||
use crate::helpers::{api_helper, requests_limit_helper};
|
||||
use crate::routes::{get_routes, RequestResult, Route};
|
||||
use crate::routes::{get_routes, RequestResult, Route, RouteScope};
|
||||
use crate::routes::Method::{GET, POST};
|
||||
use crate::utils::user_data_utils::user_data_path;
|
||||
|
||||
@ -209,14 +209,33 @@ fn process_simple_route(route: &Route, req: &mut HttpRequestHandler) -> RequestR
|
||||
req.too_many_requests("Too many request. Please try again later.")?;
|
||||
}
|
||||
|
||||
// Validate client token
|
||||
req.check_client_token()?;
|
||||
// Check if the user is allowed to access the route
|
||||
match route.scope {
|
||||
|
||||
// Check user token, if required
|
||||
if route.need_login || req.has_post_parameter("userToken1") {
|
||||
req.check_user_token()?;
|
||||
// "Normal" user route
|
||||
RouteScope::USER => {
|
||||
// Validate client token
|
||||
req.check_client_token()?;
|
||||
|
||||
// Check user token, if required
|
||||
if route.need_login || req.has_post_parameter("token") {
|
||||
req.check_user_token()?;
|
||||
}
|
||||
},
|
||||
|
||||
// "Admin" user scope
|
||||
RouteScope::ADMIN => {
|
||||
req.check_admin_origin()?;
|
||||
|
||||
if route.need_login {
|
||||
// TODO : implement
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
let res: RequestResult = (route.func)(req);
|
||||
|
||||
requests_limit_helper::trigger_after(res.is_ok(), req, route)?;
|
||||
@ -250,7 +269,7 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
|
||||
|
||||
// Check if a route was found
|
||||
if let None = route {
|
||||
return HttpResponse::NotFound().json(HttpError::not_found("Method not found!"));
|
||||
return HttpResponse::NotFound().json(HttpError::not_found("Route not found!"));
|
||||
}
|
||||
let route = route.unwrap();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user