sncf/src/sniff.rs

103 lines
2.9 KiB
Rust

use actix_web::web;
use serde_json::Value;
use crate::debug;
// checks to be done on user requests
// if it returns true, cancels the request
pub fn check_request(route: &str, body: &web::Bytes) -> bool {
match route {
"/ocs/v2.php/apps/forms/api/v1/form/update" => rq_form_update(body),
_ => false,
}
}
// prevents the user from doing anything other than link sharing.
fn rq_form_update(body: &web::Bytes) -> bool {
let req = String::from_utf8_lossy(body);
// try to serialize the body.
// If the parsing fails, drop the request
let v: Value = serde_json::from_str(&req).unwrap_or_else(|e| {
eprintln!("check_request: failed to parse JSON: {}", e);
Value::Null
});
// if the type or isAnonymous is set (isn't null),
// drop the request.
// Also drop if v is null because of parsing fail.
v == Value::Null
|| v["keyValuePairs"]["isAnonymous"] != Value::Null
|| v["keyValuePairs"]["access"]["type"] != Value::Null
}
// checks to be done on responses from the Nextcloud instance
// if it returns true, cancels the request
// NOTE: unused for now
/*pub fn check_response(_route: &str, _body: &web::Bytes) -> bool {
false
}*/
// checks if a form has been created.
// if it's the case, sets some parameters.
// this part may need code quality improvements
// the body MUST come from the "create new form" route
// (this is checked upstream)
// returns the form UID and the request body
pub fn check_new_form(body: &web::Bytes) -> u64 {
let req = String::from_utf8_lossy(body);
// finds the form ID
let v: Value = serde_json::from_str(&req).unwrap_or_else(|e| {
eprintln!("check_new_form: failed to parse JSON: {}", e);
Value::Null
});
if v != Value::Null
&& v["ocs"].is_object()
&& v["ocs"]["data"].is_object()
&& v["ocs"]["data"]["id"] != Value::Null
&& v["ocs"]["data"]["isAnonymous"] == Value::Null
{
//getting form id
v["ocs"]["data"]["id"].as_u64().unwrap_or_else(|| {
eprintln!("check_new_form: failed to parse formid: {}", v);
0
})
} else {
eprintln!("error: check_new_form: can't find formid: {}", v);
0
}
}
// those routes won't be redirected
const BLOCKED_ROUTES: &[&str] = &[
"/apps/settings",
"/login",
"/settings",
"/ocs/v",
"/remote.php",
"/apps/files",
"/core/templates/filepicker.html",
];
// ...except if they are in this list
const ALLOWED_ROUTES: &[&str] = &["/ocs/v2.php/apps/forms/", "/status.php"];
// checks if the accessed route is allowed for the user.
// if it returns true, redirects elsewhere
pub fn check_route(route: &str) -> bool {
debug(route);
for r in BLOCKED_ROUTES {
if route.starts_with(r) {
for s in ALLOWED_ROUTES {
if route.starts_with(s) {
return false;
}
}
return true;
}
}
false
}