mirror of
https://git.42l.fr/neil/sncf.git
synced 2024-05-04 15:03:12 +02:00
cargo fmt
This commit is contained in:
parent
3d6b9f96e8
commit
c1191f3f45
|
@ -1,15 +1,15 @@
|
||||||
use actix_web::client::Client;
|
use actix_web::client::Client;
|
||||||
use actix_web::{http, web, HttpRequest, HttpResponse};
|
use actix_web::{http, web, HttpRequest, HttpResponse};
|
||||||
use base64::URL_SAFE_NO_PAD;
|
use base64::URL_SAFE_NO_PAD;
|
||||||
|
use percent_encoding::percent_decode_str;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::time::Duration;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use percent_encoding::percent_decode_str;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::config::{PROXY_TIMEOUT, USER_AGENT, ADJ_LIST, NAME_LIST};
|
use crate::config::{ADJ_LIST, NAME_LIST, PROXY_TIMEOUT, USER_AGENT};
|
||||||
use crate::debug;
|
use crate::debug;
|
||||||
use crate::errors::{crash, TrainCrash};
|
use crate::errors::{crash, TrainCrash};
|
||||||
use crate::templates::get_lang;
|
use crate::templates::get_lang;
|
||||||
|
@ -169,20 +169,22 @@ pub async fn login(
|
||||||
crash(get_lang(&req), "error_login_cookiepair")
|
crash(get_lang(&req), "error_login_cookiepair")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// percent decode
|
// percent decode
|
||||||
let c_str = percent_decode_str(c_str).decode_utf8_lossy();
|
let c_str = percent_decode_str(c_str).decode_utf8_lossy();
|
||||||
|
|
||||||
//then remove values after ';'
|
//then remove values after ';'
|
||||||
let c_str_arr = c_str.split(';').collect::<Vec<&str>>();
|
let c_str_arr = c_str.split(';').collect::<Vec<&str>>();
|
||||||
|
|
||||||
let c_str = c_str_arr.first()
|
let c_str = c_str_arr
|
||||||
|
.first()
|
||||||
.expect("error: cookiepair split does not have a first value. shouldn't happen.");
|
.expect("error: cookiepair split does not have a first value. shouldn't happen.");
|
||||||
|
|
||||||
// split cookie key and cookie value
|
// split cookie key and cookie value
|
||||||
// split_once would work best but it's nightly-only for now
|
// split_once would work best but it's nightly-only for now
|
||||||
let c_str_arr = c_str.split('=').collect::<Vec<&str>>();
|
let c_str_arr = c_str.split('=').collect::<Vec<&str>>();
|
||||||
|
|
||||||
let c_key = c_str_arr.first()
|
let c_key = c_str_arr
|
||||||
|
.first()
|
||||||
.expect("error: cookie key split does not have a first value, shouldn't happen.");
|
.expect("error: cookie key split does not have a first value, shouldn't happen.");
|
||||||
|
|
||||||
let c_value = c_str.replace(&format!("{}=", c_key), "");
|
let c_value = c_str.replace(&format!("{}=", c_key), "");
|
||||||
|
@ -192,12 +194,10 @@ pub async fn login(
|
||||||
// else, insert it
|
// else, insert it
|
||||||
if let Some(c_sel) = cookie_map.get_mut(*c_key) {
|
if let Some(c_sel) = cookie_map.get_mut(*c_key) {
|
||||||
*c_sel = c_value;
|
*c_sel = c_value;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
cookie_map.insert(c_key.to_string(), c_value);
|
cookie_map.insert(c_key.to_string(), c_value);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
eprintln!("error_login_cookiepair (2)");
|
eprintln!("error_login_cookiepair (2)");
|
||||||
return Err(crash(get_lang(&req), "error_login_cookiepair"));
|
return Err(crash(get_lang(&req), "error_login_cookiepair"));
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,7 @@ pub async fn login(
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref RE: Regex = Regex::new(r#"\{"token":"(?P<token>[^"]*)"\}"#)
|
static ref RE: Regex = Regex::new(r#"\{"token":"(?P<token>[^"]*)"\}"#)
|
||||||
.expect("Error while parsing the requesttoken regex");
|
.expect("Error while parsing the requesttoken regex");
|
||||||
}
|
}
|
||||||
|
|
||||||
let post_body = login_get.body().await.map_err(|e| {
|
let post_body = login_get.body().await.map_err(|e| {
|
||||||
eprintln!("error_login_get_body: {}", e);
|
eprintln!("error_login_get_body: {}", e);
|
||||||
|
@ -228,12 +228,12 @@ pub async fn login(
|
||||||
eprintln!("error_login_regex (no capture)");
|
eprintln!("error_login_regex (no capture)");
|
||||||
crash(get_lang(&req), "error_login_regex")
|
crash(get_lang(&req), "error_login_regex")
|
||||||
})?
|
})?
|
||||||
.name("token")
|
.name("token")
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
eprintln!("error_login_regex (no capture named token)");
|
eprintln!("error_login_regex (no capture named token)");
|
||||||
crash(get_lang(&req), "error_login_regex")
|
crash(get_lang(&req), "error_login_regex")
|
||||||
})?
|
})?
|
||||||
.as_str();
|
.as_str();
|
||||||
|
|
||||||
// 2. POST /login
|
// 2. POST /login
|
||||||
let mut login_post = client
|
let mut login_post = client
|
||||||
|
@ -253,7 +253,7 @@ pub async fn login(
|
||||||
timezone_offset: "2",
|
timezone_offset: "2",
|
||||||
requesttoken,
|
requesttoken,
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
eprintln!("error_login_post: {}", e);
|
eprintln!("error_login_post: {}", e);
|
||||||
crash(get_lang(&req), "error_login_post")
|
crash(get_lang(&req), "error_login_post")
|
||||||
|
|
|
@ -2,13 +2,13 @@ use actix_web::client::{Client, ClientRequest};
|
||||||
use actix_web::{http, web, HttpRequest, HttpResponse};
|
use actix_web::{http, web, HttpRequest, HttpResponse};
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
|
use csrf::{AesGcmCsrfProtection, CsrfProtection};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use csrf::{AesGcmCsrfProtection, CsrfProtection};
|
|
||||||
|
|
||||||
use crate::config::get_csrf_key;
|
|
||||||
use crate::account::*;
|
use crate::account::*;
|
||||||
|
use crate::config::get_csrf_key;
|
||||||
use crate::config::PAYLOAD_LIMIT;
|
use crate::config::PAYLOAD_LIMIT;
|
||||||
use crate::config::PROXY_TIMEOUT;
|
use crate::config::PROXY_TIMEOUT;
|
||||||
use crate::database::methods::InsertableForm;
|
use crate::database::methods::InsertableForm;
|
||||||
|
@ -250,15 +250,20 @@ pub async fn forward_register(
|
||||||
})?
|
})?
|
||||||
.as_str();
|
.as_str();
|
||||||
|
|
||||||
let raw_ctoken = base64::decode_config(cookie_csrf_token.as_bytes(), base64::URL_SAFE_NO_PAD).map_err(|e| {
|
let raw_ctoken =
|
||||||
eprintln!("error_csrf_cookie (base64): {}", e);
|
base64::decode_config(cookie_csrf_token.as_bytes(), base64::URL_SAFE_NO_PAD).map_err(
|
||||||
crash(get_lang(&req), "error_csrf_cookie")
|
|e| {
|
||||||
})?;
|
eprintln!("error_csrf_cookie (base64): {}", e);
|
||||||
|
crash(get_lang(&req), "error_csrf_cookie")
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
let raw_token = base64::decode_config(csrf_post.csrf_token.as_bytes(), base64::URL_SAFE_NO_PAD).map_err(|e| {
|
let raw_token =
|
||||||
eprintln!("error_csrf_token (base64): {}", e);
|
base64::decode_config(csrf_post.csrf_token.as_bytes(), base64::URL_SAFE_NO_PAD)
|
||||||
crash(get_lang(&req), "error_csrf_token")
|
.map_err(|e| {
|
||||||
})?;
|
eprintln!("error_csrf_token (base64): {}", e);
|
||||||
|
crash(get_lang(&req), "error_csrf_token")
|
||||||
|
})?;
|
||||||
|
|
||||||
let seed = AesGcmCsrfProtection::from_key(get_csrf_key());
|
let seed = AesGcmCsrfProtection::from_key(get_csrf_key());
|
||||||
let parsed_token = seed.parse_token(&raw_token).expect("token not parsed");
|
let parsed_token = seed.parse_token(&raw_token).expect("token not parsed");
|
||||||
|
@ -267,8 +272,7 @@ pub async fn forward_register(
|
||||||
debug("warn: CSRF token doesn't match.");
|
debug("warn: CSRF token doesn't match.");
|
||||||
return Err(crash(lang, "error_csrf_token"));
|
return Err(crash(lang, "error_csrf_token"));
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
debug("warn: missing CSRF token.");
|
debug("warn: missing CSRF token.");
|
||||||
return Err(crash(lang, "error_csrf_cookie"));
|
return Err(crash(lang, "error_csrf_cookie"));
|
||||||
}
|
}
|
||||||
|
@ -291,16 +295,18 @@ pub async fn forward_register(
|
||||||
let token_mv = token.clone();
|
let token_mv = token.clone();
|
||||||
|
|
||||||
// store the result in DB
|
// store the result in DB
|
||||||
let form_result = web::block(move || Form::insert(
|
let form_result = web::block(move || {
|
||||||
InsertableForm {
|
Form::insert(
|
||||||
created_at: Utc::now().naive_utc(),
|
InsertableForm {
|
||||||
lastvisit_at: Utc::now().naive_utc(),
|
created_at: Utc::now().naive_utc(),
|
||||||
token: token_mv,
|
lastvisit_at: Utc::now().naive_utc(),
|
||||||
nc_username,
|
token: token_mv,
|
||||||
nc_password,
|
nc_username,
|
||||||
},
|
nc_password,
|
||||||
&conn,
|
},
|
||||||
))
|
&conn,
|
||||||
|
)
|
||||||
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if form_result.is_err() {
|
if form_result.is_err() {
|
||||||
|
@ -365,17 +371,20 @@ fn web_redir(location: &str) -> HttpResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn index(req: HttpRequest) -> Result<HttpResponse, TrainCrash> {
|
pub async fn index(req: HttpRequest) -> Result<HttpResponse, TrainCrash> {
|
||||||
|
|
||||||
let seed = AesGcmCsrfProtection::from_key(get_csrf_key());
|
let seed = AesGcmCsrfProtection::from_key(get_csrf_key());
|
||||||
let (csrf_token, csrf_cookie) = seed.generate_token_pair(None, 43200)
|
let (csrf_token, csrf_cookie) = seed
|
||||||
|
.generate_token_pair(None, 43200)
|
||||||
.expect("couldn't generate token/cookie pair");
|
.expect("couldn't generate token/cookie pair");
|
||||||
|
|
||||||
Ok(HttpResponse::Ok()
|
Ok(HttpResponse::Ok()
|
||||||
.content_type("text/html")
|
.content_type("text/html")
|
||||||
.set_header(
|
.set_header(
|
||||||
"Set-Cookie",
|
"Set-Cookie",
|
||||||
format!("sncf_csrf_cookie={}; HttpOnly; SameSite=Strict",
|
format!(
|
||||||
base64::encode_config(&csrf_cookie.value(), base64::URL_SAFE_NO_PAD)))
|
"sncf_csrf_cookie={}; HttpOnly; SameSite=Strict",
|
||||||
|
base64::encode_config(&csrf_cookie.value(), base64::URL_SAFE_NO_PAD)
|
||||||
|
),
|
||||||
|
)
|
||||||
.body(
|
.body(
|
||||||
TplIndex {
|
TplIndex {
|
||||||
lang: &get_lang(&req),
|
lang: &get_lang(&req),
|
||||||
|
|
32
src/sniff.rs
32
src/sniff.rs
|
@ -54,20 +54,19 @@ pub fn check_new_form(body: &web::Bytes) -> u64 {
|
||||||
|
|
||||||
if v != Value::Null
|
if v != Value::Null
|
||||||
&& v["ocs"].is_object()
|
&& v["ocs"].is_object()
|
||||||
&& v["ocs"]["data"].is_object()
|
&& v["ocs"]["data"].is_object()
|
||||||
&& v["ocs"]["data"]["id"] != Value::Null
|
&& v["ocs"]["data"]["id"] != Value::Null
|
||||||
&& v["ocs"]["data"]["isAnonymous"] == Value::Null {
|
&& v["ocs"]["data"]["isAnonymous"] == Value::Null
|
||||||
|
{
|
||||||
//getting form id
|
//getting form id
|
||||||
let new_v_id = v["ocs"]["data"]["id"].as_u64().unwrap_or_else(|| {
|
let new_v_id = v["ocs"]["data"]["id"].as_u64().unwrap_or_else(|| {
|
||||||
eprintln!("check_new_form: failed to parse formid: {}", v);
|
eprintln!("check_new_form: failed to parse formid: {}", v);
|
||||||
0
|
0
|
||||||
});
|
});
|
||||||
new_v_id
|
new_v_id
|
||||||
|
} else {
|
||||||
} else {
|
eprintln!("error: check_new_form: can't find formid: {}", v);
|
||||||
eprintln!("error: check_new_form: can't find formid: {}", v);
|
0
|
||||||
0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +82,7 @@ const BLOCKED_ROUTES: &[&str] = &[
|
||||||
];
|
];
|
||||||
|
|
||||||
// ...except if they are in this list
|
// ...except if they are in this list
|
||||||
const ALLOWED_ROUTES: &[&str] = &[
|
const ALLOWED_ROUTES: &[&str] = &["/ocs/v2.php/apps/forms/", "/status.php"];
|
||||||
"/ocs/v2.php/apps/forms/",
|
|
||||||
"/status.php"
|
|
||||||
];
|
|
||||||
|
|
||||||
// checks if the accessed route is allowed for the user.
|
// checks if the accessed route is allowed for the user.
|
||||||
// if it returns true, redirects elsewhere
|
// if it returns true, redirects elsewhere
|
||||||
|
|
Loading…
Reference in a new issue