mirror of
https://gitlab.com/comunic/comunicapiv3
synced 2024-11-22 21:39:21 +00:00
Handle pre-flight requests
This commit is contained in:
parent
c29d8b1997
commit
eb0c7aec6a
@ -13,9 +13,6 @@ server-port: 3000
|
|||||||
# This value is used to trust upstream proxy
|
# This value is used to trust upstream proxy
|
||||||
proxy: "127.0.0.1"
|
proxy: "127.0.0.1"
|
||||||
|
|
||||||
# If set to true Access-Control-Allow-Origin will be set for https
|
|
||||||
force-https: true
|
|
||||||
|
|
||||||
# User data storage
|
# User data storage
|
||||||
storage-url: http://devweb.local/comunic/current/user_data/
|
storage-url: http://devweb.local/comunic/current/user_data/
|
||||||
storage-path: /home/pierre/Documents/projets_web/comunic/current/user_data/
|
storage-path: /home/pierre/Documents/projets_web/comunic/current/user_data/
|
||||||
|
@ -35,7 +35,6 @@ pub struct Config {
|
|||||||
pub play_store_url: String,
|
pub play_store_url: String,
|
||||||
pub android_direct_download_url: String,
|
pub android_direct_download_url: String,
|
||||||
pub proxy: Option<String>,
|
pub proxy: Option<String>,
|
||||||
pub force_https: bool,
|
|
||||||
pub verbose_mode: bool,
|
pub verbose_mode: bool,
|
||||||
pub database: DatabaseConfig,
|
pub database: DatabaseConfig,
|
||||||
pub rtc_relay: Option<RtcRelayConfig>,
|
pub rtc_relay: Option<RtcRelayConfig>,
|
||||||
@ -116,8 +115,6 @@ impl Config {
|
|||||||
s => Some(s.to_string())
|
s => Some(s.to_string())
|
||||||
},
|
},
|
||||||
|
|
||||||
force_https: Config::yaml_bool(parsed, "force-https"),
|
|
||||||
|
|
||||||
verbose_mode: Config::yaml_bool(parsed, "verbose-mode"),
|
verbose_mode: Config::yaml_bool(parsed, "verbose-mode"),
|
||||||
|
|
||||||
database: database_conf,
|
database: database_conf,
|
||||||
|
@ -7,13 +7,13 @@ use actix_web::http::{HeaderName, HeaderValue, StatusCode};
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::api_data::http_error::HttpError;
|
use crate::api_data::http_error::HttpError;
|
||||||
use crate::routes::RequestResult;
|
|
||||||
use crate::data::api_client::APIClient;
|
use crate::data::api_client::APIClient;
|
||||||
use crate::data::base_request_handler::{BaseRequestHandler, RequestValue};
|
use crate::data::base_request_handler::{BaseRequestHandler, RequestValue};
|
||||||
use crate::data::config::conf;
|
use crate::data::config::conf;
|
||||||
use crate::data::error::{Res, ResultBoxError};
|
use crate::data::error::{Res, ResultBoxError};
|
||||||
use crate::data::user_token::UserAccessToken;
|
use crate::data::user_token::UserAccessToken;
|
||||||
use crate::helpers::{account_helper, api_helper};
|
use crate::helpers::{account_helper, api_helper};
|
||||||
|
use crate::routes::RequestResult;
|
||||||
|
|
||||||
/// Http request handler
|
/// Http request handler
|
||||||
///
|
///
|
||||||
@ -86,22 +86,17 @@ impl HttpRequestHandler {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
||||||
if let Some(domain) = &client.domain {
|
if let Some(allowed_origin) = &client.domain {
|
||||||
let allowed_origin = match conf().force_https {
|
|
||||||
true => format!("https://{}", domain),
|
|
||||||
false => format!("http://{}", domain)
|
|
||||||
};
|
|
||||||
|
|
||||||
match self.request.headers().get("Referer") {
|
match self.request.headers().get("Referer") {
|
||||||
None => self.bad_request("Unknown origin!".to_string())?,
|
None => self.bad_request("Unknown origin!".to_string())?,
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
if !s.to_str()?.starts_with(&allowed_origin) {
|
if !s.to_str()?.starts_with(allowed_origin) {
|
||||||
self.bad_request("Use of this client is prohibited from this domain!".to_string())?;
|
self.bad_request("Use of this client is prohibited from this domain!".to_string())?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.headers.insert("Access-Control-Allow-Origin".to_string(), allowed_origin);
|
self.headers.insert("Access-Control-Allow-Origin".to_string(), allowed_origin.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.client = Some(client);
|
self.client = Some(client);
|
||||||
|
@ -1,17 +1,29 @@
|
|||||||
use crate::constants::database_tables_names::CLIENTS_TABLE;
|
use crate::constants::database_tables_names::CLIENTS_TABLE;
|
||||||
use crate::data::api_client::APIClient;
|
use crate::data::api_client::APIClient;
|
||||||
use crate::data::error::ResultBoxError;
|
use crate::data::error::{Res, ResultBoxError};
|
||||||
|
use crate::helpers::database;
|
||||||
use crate::helpers::database::QueryInfo;
|
use crate::helpers::database::QueryInfo;
|
||||||
|
|
||||||
/// API helper
|
/// API helper
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
/// Get information about a client
|
/// Get information about a client, based on its token
|
||||||
pub fn get_client(name: &str) -> ResultBoxError<APIClient> {
|
pub fn get_client(name: &str) -> ResultBoxError<APIClient> {
|
||||||
QueryInfo::new(CLIENTS_TABLE)
|
QueryInfo::new(CLIENTS_TABLE)
|
||||||
.cond("name", name)
|
.cond("name", name)
|
||||||
.query_row(|res| {
|
.query_row(db_to_client)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Get information about a client, based on its origin
|
||||||
|
pub fn get_by_origin(name: &str) -> ResultBoxError<APIClient> {
|
||||||
|
QueryInfo::new(CLIENTS_TABLE)
|
||||||
|
.cond("domain", name)
|
||||||
|
.query_row(db_to_client)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn db_to_client(res: &database::RowResult) -> Res<APIClient> {
|
||||||
Ok(APIClient {
|
Ok(APIClient {
|
||||||
id: res.get_u64("id")?,
|
id: res.get_u64("id")?,
|
||||||
name: res.get_str("name")?,
|
name: res.get_str("name")?,
|
||||||
@ -19,5 +31,4 @@ pub fn get_client(name: &str) -> ResultBoxError<APIClient> {
|
|||||||
comment: res.get_optional_str("comment")?,
|
comment: res.get_optional_str("comment")?,
|
||||||
default_expiration_time: res.get_u64("default_expiration_time")?,
|
default_expiration_time: res.get_u64("default_expiration_time")?,
|
||||||
})
|
})
|
||||||
})
|
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ use std::pin::Pin;
|
|||||||
use actix_web::{App, FromRequest, http, HttpMessage, HttpRequest, HttpResponse, HttpServer, web};
|
use actix_web::{App, FromRequest, http, HttpMessage, HttpRequest, HttpResponse, HttpServer, web};
|
||||||
use actix_web::dev::{Decompress, Payload, PayloadStream};
|
use actix_web::dev::{Decompress, Payload, PayloadStream};
|
||||||
use actix_web::error::{ErrorBadRequest, ErrorInternalServerError, PayloadError};
|
use actix_web::error::{ErrorBadRequest, ErrorInternalServerError, PayloadError};
|
||||||
use actix_web::web::{Bytes, BytesMut, BufMut, Buf};
|
use actix_web::web::{Buf, BufMut, Bytes, BytesMut};
|
||||||
use encoding_rs::UTF_8;
|
use encoding_rs::UTF_8;
|
||||||
use futures::{FutureExt, Stream, StreamExt};
|
use futures::{FutureExt, Stream, StreamExt};
|
||||||
use futures::future::LocalBoxFuture;
|
use futures::future::LocalBoxFuture;
|
||||||
@ -14,12 +14,12 @@ use percent_encoding::percent_decode_str;
|
|||||||
use crate::api_data::http_error::HttpError;
|
use crate::api_data::http_error::HttpError;
|
||||||
use crate::constants::MAX_REQUEST_SIZE;
|
use crate::constants::MAX_REQUEST_SIZE;
|
||||||
use crate::controllers::{rtc_relay_controller, user_ws_controller};
|
use crate::controllers::{rtc_relay_controller, user_ws_controller};
|
||||||
use crate::routes::{get_routes, RequestResult, Route};
|
|
||||||
use crate::routes::Method::{GET, POST};
|
|
||||||
use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestValue};
|
use crate::data::base_request_handler::{BaseRequestHandler, PostFile, RequestValue};
|
||||||
use crate::data::config::Config;
|
use crate::data::config::Config;
|
||||||
use crate::data::http_request_handler::HttpRequestHandler;
|
use crate::data::http_request_handler::HttpRequestHandler;
|
||||||
use crate::helpers::requests_limit_helper;
|
use crate::helpers::{api_helper, requests_limit_helper};
|
||||||
|
use crate::routes::{get_routes, RequestResult, Route};
|
||||||
|
use crate::routes::Method::{GET, POST};
|
||||||
|
|
||||||
/// Main server functions
|
/// Main server functions
|
||||||
///
|
///
|
||||||
@ -301,6 +301,30 @@ async fn process_request(custom_req: CustomRequest) -> HttpResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle pre-flight requests
|
||||||
|
async fn handle_options_request(r: HttpRequest) -> HttpResponse {
|
||||||
|
|
||||||
|
// Extract origin
|
||||||
|
let origin = r.headers().get("Origin");
|
||||||
|
if origin.is_none() {
|
||||||
|
return HttpResponse::BadRequest().body("Missing origin header!");
|
||||||
|
}
|
||||||
|
let origin = origin.unwrap().to_str().unwrap_or("").to_string();
|
||||||
|
|
||||||
|
// Find client
|
||||||
|
let client = api_helper::get_by_origin(&origin);
|
||||||
|
if client.is_err() {
|
||||||
|
eprintln!("Failed to handle OPTIONS request: {:#?}", client);
|
||||||
|
return HttpResponse::Unauthorized().body("Unkown origin!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept request
|
||||||
|
HttpResponse::NoContent()
|
||||||
|
.header("Access-Control-Allow-Origin", origin)
|
||||||
|
.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Given the configuration, start the server
|
/// Given the configuration, start the server
|
||||||
pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
||||||
@ -320,6 +344,9 @@ pub async fn start_server(conf: &Config) -> std::io::Result<()> {
|
|||||||
// RTC Relay WebSocket route
|
// RTC Relay WebSocket route
|
||||||
.service(actix_web::web::resource("/rtc_proxy/ws").to(rtc_relay_controller::open_ws))
|
.service(actix_web::web::resource("/rtc_proxy/ws").to(rtc_relay_controller::open_ws))
|
||||||
|
|
||||||
|
// Option
|
||||||
|
.route("**", web::method(http::Method::OPTIONS).to(handle_options_request))
|
||||||
|
|
||||||
// API routes
|
// API routes
|
||||||
.route("**", web::get().to(process_request))
|
.route("**", web::get().to(process_request))
|
||||||
.route("**", web::post().to(process_request))
|
.route("**", web::post().to(process_request))
|
||||||
|
Loading…
Reference in New Issue
Block a user