mirror of
https://git.42l.fr/neil/sncf.git
synced 2024-05-05 23:43:10 +02:00
cargo fmt
This commit is contained in:
parent
20400a798f
commit
05566dde3d
|
@ -7,12 +7,12 @@ use rand::RngCore;
|
|||
use regex::Regex;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::templates::get_lang;
|
||||
use crate::config::{ADJ_LIST, NAME_LIST};
|
||||
use crate::errors::{crash, TrainCrash};
|
||||
use crate::debug;
|
||||
use crate::CONFIG;
|
||||
use crate::config::PROXY_TIMEOUT;
|
||||
use crate::config::{ADJ_LIST, NAME_LIST};
|
||||
use crate::debug;
|
||||
use crate::errors::{crash, TrainCrash};
|
||||
use crate::templates::get_lang;
|
||||
use crate::CONFIG;
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct NCLoginForm<'a> {
|
||||
|
@ -140,7 +140,8 @@ pub async fn login(
|
|||
.timeout(Duration::new(PROXY_TIMEOUT, 0))
|
||||
.header("User-Agent", "Actix-web")
|
||||
.send()
|
||||
.await.map_err(|e| {
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("error_login_get: {}", e);
|
||||
crash(get_lang(&req), "error_login_get")
|
||||
})?;
|
||||
|
@ -148,15 +149,20 @@ pub async fn login(
|
|||
// rewrite cookie headers from GET to POST
|
||||
let mut str_cookiepair = String::new();
|
||||
for h_value in login_get.headers().get_all("set-cookie") {
|
||||
str_cookiepair = format!("{}; {}", str_cookiepair, h_value.clone().to_str().map_err(|e| {
|
||||
eprintln!("error_login_cookiepair: {}", e);
|
||||
crash(get_lang(&req), "error_login_cookiepair")
|
||||
})?);
|
||||
str_cookiepair = format!(
|
||||
"{}; {}",
|
||||
str_cookiepair,
|
||||
h_value.clone().to_str().map_err(|e| {
|
||||
eprintln!("error_login_cookiepair: {}", e);
|
||||
crash(get_lang(&req), "error_login_cookiepair")
|
||||
})?
|
||||
);
|
||||
}
|
||||
|
||||
// load requesttoken regex
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(r#"requesttoken="(?P<token>.*)""#).expect("Error while parsing the requesttoken regex");
|
||||
static ref RE: Regex = Regex::new(r#"requesttoken="(?P<token>.*)""#)
|
||||
.expect("Error while parsing the requesttoken regex");
|
||||
}
|
||||
|
||||
let post_body = login_get.body().await.map_err(|e| {
|
||||
|
@ -172,12 +178,12 @@ pub async fn login(
|
|||
eprintln!("error_login_regex (no capture)");
|
||||
crash(get_lang(&req), "error_login_regex")
|
||||
})?
|
||||
.name("token")
|
||||
.name("token")
|
||||
.ok_or_else(|| {
|
||||
eprintln!("error_login_regex (no capture named token)");
|
||||
crash(get_lang(&req), "error_login_regex")
|
||||
})?
|
||||
.as_str();
|
||||
.as_str();
|
||||
|
||||
// 2. POST /login
|
||||
let mut login_post = client
|
||||
|
@ -197,25 +203,30 @@ pub async fn login(
|
|||
timezone_offset: "2",
|
||||
requesttoken,
|
||||
})
|
||||
.await.map_err(|e| {
|
||||
eprintln!("error_login_post: {}", e);
|
||||
crash(get_lang(&req), "error_login_post")
|
||||
})?;
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("error_login_post: {}", e);
|
||||
crash(get_lang(&req), "error_login_post")
|
||||
})?;
|
||||
|
||||
// 3. set the same cookies in the user's browser
|
||||
let mut user_response = HttpResponse::SeeOther();
|
||||
for item in response_post.headers().clone().get_all("set-cookie") {
|
||||
user_response.header("Set-Cookie", item.to_str().map_err(|e| {
|
||||
eprintln!("error_login_setcookie: {}", e);
|
||||
crash(get_lang(&req), "error_login_setcookie")
|
||||
})?);
|
||||
user_response.header(
|
||||
"Set-Cookie",
|
||||
item.to_str().map_err(|e| {
|
||||
eprintln!("error_login_setcookie: {}", e);
|
||||
crash(get_lang(&req), "error_login_setcookie")
|
||||
})?,
|
||||
);
|
||||
}
|
||||
|
||||
// redirect to forms!
|
||||
Ok(user_response
|
||||
.header(http::header::LOCATION, "/apps/forms")
|
||||
.finish()
|
||||
.await.map_err(|e| {
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("error_login_redir: {}", e);
|
||||
crash(get_lang(&req), "error_login_redir")
|
||||
})?)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use serde_json::Value;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::io::{self, BufRead, BufReader};
|
||||
use std::path::Path;
|
||||
use serde_json::Value;
|
||||
|
||||
// payload limit set to 5MiB
|
||||
pub const PAYLOAD_LIMIT: usize = 10_000_000;
|
||||
|
|
|
@ -2,9 +2,9 @@ use chrono::NaiveDateTime;
|
|||
use chrono::Utc;
|
||||
use diesel::prelude::*;
|
||||
|
||||
use crate::database::schema::form;
|
||||
use crate::database::schema::form::dsl::*;
|
||||
use crate::database::structs::Form;
|
||||
use crate::database::schema::form;
|
||||
use crate::SqliteConnection;
|
||||
|
||||
#[table_name = "form"]
|
||||
|
@ -24,7 +24,11 @@ impl Form {
|
|||
i_token: &str,
|
||||
conn: &SqliteConnection,
|
||||
) -> Result<Option<Form>, diesel::result::Error> {
|
||||
if let Some(formdata) = form.filter(token.eq(i_token)).first::<Form>(conn).optional()? {
|
||||
if let Some(formdata) = form
|
||||
.filter(token.eq(i_token))
|
||||
.first::<Form>(conn)
|
||||
.optional()?
|
||||
{
|
||||
match formdata.update_lastvisit(conn) {
|
||||
Ok(_) => Ok(Some(formdata)),
|
||||
Err(e) => Err(e),
|
||||
|
@ -34,13 +38,18 @@ impl Form {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_lastvisit(&self, conn: &SqliteConnection) -> Result<usize, diesel::result::Error> {
|
||||
pub fn update_lastvisit(
|
||||
&self,
|
||||
conn: &SqliteConnection,
|
||||
) -> Result<usize, diesel::result::Error> {
|
||||
diesel::update(form.find(self.id))
|
||||
.set(lastvisit_at.eq(Utc::now().naive_utc()))
|
||||
.execute(conn)
|
||||
}
|
||||
|
||||
pub fn insert<'b>(i_form: InsertableForm<'b>, conn: &SqliteConnection
|
||||
|
||||
pub fn insert<'b>(
|
||||
i_form: InsertableForm<'b>,
|
||||
conn: &SqliteConnection,
|
||||
) -> Result<InsertableForm<'b>, diesel::result::Error> {
|
||||
match diesel::insert_into(form).values(&i_form).execute(conn) {
|
||||
Ok(_) => Ok(i_form),
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
pub mod methods;
|
||||
pub mod schema;
|
||||
pub mod structs;
|
||||
pub mod methods;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::templates::TplError;
|
||||
|
||||
use std::fmt;
|
||||
use actix_web::dev::HttpResponseBuilder;
|
||||
use actix_web::{error, http::header, http::StatusCode, HttpResponse};
|
||||
use askama::Template;
|
||||
use std::fmt;
|
||||
|
||||
pub fn crash(lang: String, error_msg: &'static str) -> TrainCrash {
|
||||
TrainCrash { lang, error_msg }
|
||||
|
@ -34,8 +34,8 @@ impl error::ResponseError for TrainCrash {
|
|||
error_msg: self.error_msg,
|
||||
}
|
||||
.render()
|
||||
.expect("error_tplrender (TplError). Empty page sent to client."))
|
||||
|
||||
.expect("error_tplrender (TplError). Empty page sent to client."),
|
||||
)
|
||||
}
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self.error_msg {
|
||||
|
|
128
src/forward.rs
128
src/forward.rs
|
@ -2,9 +2,9 @@ use actix_web::client::{Client, ClientRequest};
|
|||
use actix_web::{http, web, HttpRequest, HttpResponse};
|
||||
use askama::Template;
|
||||
use chrono::Utc;
|
||||
use url::Url;
|
||||
use regex::Regex;
|
||||
use std::time::Duration;
|
||||
use url::Url;
|
||||
|
||||
use crate::account::*;
|
||||
use crate::config::PAYLOAD_LIMIT;
|
||||
|
@ -12,11 +12,11 @@ use crate::config::PROXY_TIMEOUT;
|
|||
use crate::database::methods::InsertableForm;
|
||||
use crate::database::structs::Form;
|
||||
use crate::debug;
|
||||
use crate::errors::{crash, TrainCrash};
|
||||
use crate::sniff::*;
|
||||
use crate::templates::*;
|
||||
use crate::DbPool;
|
||||
use crate::CONFIG;
|
||||
use crate::errors::{TrainCrash, crash};
|
||||
|
||||
pub async fn forward(
|
||||
req: HttpRequest,
|
||||
|
@ -40,8 +40,8 @@ pub async fn forward(
|
|||
// (prevents the user from sending some specific POST requests)
|
||||
if check_request(route, &body) {
|
||||
debug(&format!(
|
||||
"Restricted request: {}",
|
||||
String::from_utf8_lossy(&body)
|
||||
"Restricted request: {}",
|
||||
String::from_utf8_lossy(&body)
|
||||
));
|
||||
return Err(crash(get_lang(&req), "error_dirtyhacker"));
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ pub async fn forward(
|
|||
// and basic-auth, because this feature is not needed.
|
||||
for (header_name, header_value) in res
|
||||
.headers()
|
||||
.iter()
|
||||
.filter(|(h, _)| *h != "connection" && *h != "content-encoding" && *h != "authorization")
|
||||
.iter()
|
||||
.filter(|(h, _)| *h != "connection" && *h != "content-encoding" && *h != "authorization")
|
||||
{
|
||||
client_resp.header(header_name.clone(), header_value.clone());
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ pub async fn forward(
|
|||
let form_id = check_new_form(route, &response_body);
|
||||
if form_id > 0 {
|
||||
debug(&format!(
|
||||
"New form. Forging request to set isAnonymous for id {}",
|
||||
form_id
|
||||
"New form. Forging request to set isAnonymous for id {}",
|
||||
form_id
|
||||
));
|
||||
|
||||
let forged_body = format!(
|
||||
|
@ -87,13 +87,10 @@ pub async fn forward(
|
|||
.set_header("content-length", forged_body.len())
|
||||
.set_header("content-type", "application/json;charset=utf-8");
|
||||
|
||||
let res = update_req
|
||||
.send_body(forged_body)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
eprintln!("error_forward_isanon: {}", e);
|
||||
crash(get_lang(&req), "error_forward_isanon")
|
||||
})?;
|
||||
let res = update_req.send_body(forged_body).await.map_err(|e| {
|
||||
eprintln!("error_forward_isanon: {}", e);
|
||||
crash(get_lang(&req), "error_forward_isanon")
|
||||
})?;
|
||||
debug(&format!("(new_form) Request returned {}", res.status()));
|
||||
}
|
||||
|
||||
|
@ -127,21 +124,21 @@ pub async fn forward_login(
|
|||
return Err(crash(get_lang(&req), "error_dirtyhacker"));
|
||||
}
|
||||
|
||||
let conn = dbpool
|
||||
.get()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_forwardlogin_db: {}", e);
|
||||
crash(get_lang(&req), "error_forwardlogin_db")
|
||||
})?;
|
||||
let conn = dbpool.get().map_err(|e| {
|
||||
eprintln!("error_forwardlogin_db: {}", e);
|
||||
crash(get_lang(&req), "error_forwardlogin_db")
|
||||
})?;
|
||||
|
||||
// check if the link exists in DB. if it does, update lastvisit_at.
|
||||
let formdata = Form::get_from_token(¶ms.token, &conn).map_err(|e| {
|
||||
eprintln!("error_forwardlogin_db_get (diesel error): {}", e);
|
||||
crash(get_lang(&req), "error_forwardlogin_db_get")
|
||||
})?.ok_or_else(|| {
|
||||
debug("Token not found.");
|
||||
crash(get_lang(&req), "error_forwardlogin_notfound")
|
||||
})?;
|
||||
let formdata = Form::get_from_token(¶ms.token, &conn)
|
||||
.map_err(|e| {
|
||||
eprintln!("error_forwardlogin_db_get (diesel error): {}", e);
|
||||
crash(get_lang(&req), "error_forwardlogin_db_get")
|
||||
})?
|
||||
.ok_or_else(|| {
|
||||
debug("Token not found.");
|
||||
crash(get_lang(&req), "error_forwardlogin_notfound")
|
||||
})?;
|
||||
|
||||
// else, try to log the user in with DB data, then redirect.
|
||||
login(&client, &req, &formdata.nc_username, &formdata.nc_password).await
|
||||
|
@ -164,30 +161,32 @@ pub async fn forward_register(
|
|||
// if the user has already generated an admin token, redirect too
|
||||
if let Some(token) = has_admintoken(&req) {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(r#"sncf_admin_token=(?P<token>[0-9A-Za-z_\-]*)"#).expect("Error while parsing the sncf_admin_token regex");
|
||||
static ref RE: Regex = Regex::new(r#"sncf_admin_token=(?P<token>[0-9A-Za-z_\-]*)"#)
|
||||
.expect("Error while parsing the sncf_admin_token regex");
|
||||
}
|
||||
let admin_token = RE.captures(&token)
|
||||
let admin_token = RE
|
||||
.captures(&token)
|
||||
.ok_or_else(|| {
|
||||
eprintln!("error_forwardregister_tokenparse (no capture)");
|
||||
crash(get_lang(&req), "error_forwardregister_tokenparse")
|
||||
})?
|
||||
.name("token")
|
||||
.name("token")
|
||||
.ok_or_else(|| {
|
||||
eprintln!("error_forwardregister_tokenparse (no capture named token)");
|
||||
crash(get_lang(&req), "error_forwardregister_tokenparse")
|
||||
})?
|
||||
.as_str();
|
||||
// sanitize the token beforehand, cookies are unsafe
|
||||
if check_token(&admin_token) {
|
||||
return Ok(web_redir(&format!(
|
||||
"{}/admin/{}",
|
||||
CONFIG.sncf_url, &admin_token
|
||||
)));
|
||||
} else {
|
||||
debug("Incorrect admin token given in cookies.");
|
||||
debug(&format!("Token: {:#?}", &admin_token));
|
||||
return Err(crash(lang, "error_dirtyhacker"));
|
||||
}
|
||||
.as_str();
|
||||
// sanitize the token beforehand, cookies are unsafe
|
||||
if check_token(&admin_token) {
|
||||
return Ok(web_redir(&format!(
|
||||
"{}/admin/{}",
|
||||
CONFIG.sncf_url, &admin_token
|
||||
)));
|
||||
} else {
|
||||
debug("Incorrect admin token given in cookies.");
|
||||
debug(&format!("Token: {:#?}", &admin_token));
|
||||
return Err(crash(lang, "error_dirtyhacker"));
|
||||
}
|
||||
}
|
||||
|
||||
let nc_username = gen_name();
|
||||
|
@ -197,12 +196,10 @@ pub async fn forward_register(
|
|||
|
||||
debug(&format!("Created user {}", nc_username));
|
||||
|
||||
let conn = dbpool
|
||||
.get()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_forwardregister_pool: {}", e);
|
||||
crash(lang.clone(), "error_forwardregister_pool")
|
||||
})?;
|
||||
let conn = dbpool.get().map_err(|e| {
|
||||
eprintln!("error_forwardregister_pool: {}", e);
|
||||
crash(lang.clone(), "error_forwardregister_pool")
|
||||
})?;
|
||||
|
||||
let token = gen_token();
|
||||
|
||||
|
@ -219,7 +216,7 @@ pub async fn forward_register(
|
|||
);
|
||||
|
||||
if form_result.is_err() {
|
||||
return Err(crash(lang, "error_forwardregister_db"))
|
||||
return Err(crash(lang, "error_forwardregister_db"));
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok()
|
||||
|
@ -233,12 +230,12 @@ pub async fn forward_register(
|
|||
lang: &lang,
|
||||
admin_token: &token,
|
||||
config: &CONFIG,
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_tplrender (TplLink): {}", e);
|
||||
crash(lang, "error_tplrender")
|
||||
})?,
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_tplrender (TplLink): {}", e);
|
||||
crash(lang, "error_tplrender")
|
||||
})?,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -255,7 +252,8 @@ fn forge_from(
|
|||
new_url.set_query(req.uri().query());
|
||||
|
||||
// insert forwarded header if we can
|
||||
let mut forwarded_req = client.request_from(new_url.as_str(), req.head())
|
||||
let mut forwarded_req = client
|
||||
.request_from(new_url.as_str(), req.head())
|
||||
.timeout(Duration::new(PROXY_TIMEOUT, 0));
|
||||
|
||||
// attempt to remove basic-auth header
|
||||
|
@ -275,13 +273,13 @@ fn web_redir(location: &str) -> HttpResponse {
|
|||
|
||||
pub async fn index(req: HttpRequest) -> Result<HttpResponse, TrainCrash> {
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(
|
||||
TplIndex {
|
||||
lang: &get_lang(&req),
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_tplrender (TplIndex): {}", e);
|
||||
crash(get_lang(&req), "error_tplrender")
|
||||
})?,
|
||||
TplIndex {
|
||||
lang: &get_lang(&req),
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| {
|
||||
eprintln!("error_tplrender (TplIndex): {}", e);
|
||||
crash(get_lang(&req), "error_tplrender")
|
||||
})?,
|
||||
))
|
||||
}
|
||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -7,9 +7,9 @@ extern crate diesel;
|
|||
#[macro_use]
|
||||
extern crate diesel_migrations;
|
||||
|
||||
use actix_files::Files;
|
||||
use actix_web::client::Client;
|
||||
use actix_web::{middleware, web, App, FromRequest, HttpServer};
|
||||
use actix_files::Files;
|
||||
use diesel::prelude::*;
|
||||
use diesel::r2d2::{self, ConnectionManager};
|
||||
use url::Url;
|
||||
|
@ -18,13 +18,13 @@ use crate::config::CONFIG;
|
|||
use crate::config::PAYLOAD_LIMIT;
|
||||
use crate::forward::*;
|
||||
|
||||
mod account;
|
||||
mod config;
|
||||
mod database;
|
||||
mod errors;
|
||||
mod forward;
|
||||
mod sniff;
|
||||
mod account;
|
||||
mod templates;
|
||||
mod errors;
|
||||
|
||||
type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
|
||||
|
||||
|
@ -32,8 +32,7 @@ embed_migrations!();
|
|||
|
||||
#[actix_rt::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
|
||||
/* std::env::set_var("RUST_LOG", "actix_web=debug");
|
||||
/* std::env::set_var("RUST_LOG", "actix_web=debug");
|
||||
env_logger::init();*/
|
||||
|
||||
println!("ta ta tala ~ SNCF init");
|
||||
|
@ -52,7 +51,8 @@ async fn main() -> std::io::Result<()> {
|
|||
println!("Running migrations...");
|
||||
embedded_migrations::run(&*conn).expect("ERROR: main: Failed to run database migrations");
|
||||
|
||||
let forward_url = Url::parse(&CONFIG.nextcloud_url).expect("Couldn't parse the forward url from config");
|
||||
let forward_url =
|
||||
Url::parse(&CONFIG.nextcloud_url).expect("Couldn't parse the forward url from config");
|
||||
|
||||
println!(
|
||||
"Now listening at {}:{}",
|
||||
|
@ -72,17 +72,16 @@ async fn main() -> std::io::Result<()> {
|
|||
.route("/", web::get().to(index))
|
||||
.route("/link", web::get().to(forward_register))
|
||||
.route("/admin/{token}", web::get().to(forward_login))
|
||||
.default_service(web::route().to(forward)).data(String::configure(|cfg| {
|
||||
.default_service(web::route().to(forward))
|
||||
.data(String::configure(|cfg| cfg.limit(PAYLOAD_LIMIT)))
|
||||
.app_data(actix_web::web::Bytes::configure(|cfg| {
|
||||
cfg.limit(PAYLOAD_LIMIT)
|
||||
}))
|
||||
.app_data(actix_web::web::Bytes::configure(|cfg| {
|
||||
cfg.limit(PAYLOAD_LIMIT)
|
||||
}))
|
||||
})
|
||||
.bind((CONFIG.listening_address.as_str(), CONFIG.listening_port))?
|
||||
.system_exit()
|
||||
.run()
|
||||
.await
|
||||
.system_exit()
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
pub fn debug(text: &str) {
|
||||
|
|
Loading…
Reference in a new issue