Browse Source

implementing multiple database systems support!

root
neil 4 months ago
parent
commit
8dd5486250
12 changed files with 79 additions and 42 deletions
  1. +7
    -1
      Cargo.toml
  2. +3
    -1
      config.toml.sample
  3. +0
    -0
      migrations/mysql/20200809180000_create_form/down.sql
  4. +8
    -0
      migrations/mysql/20200809180000_create_form/up.sql
  5. +1
    -0
      migrations/postgres/20200809180000_create_form/down.sql
  6. +8
    -0
      migrations/postgres/20200809180000_create_form/up.sql
  7. +1
    -0
      migrations/sqlite/20200809180000_create_form/down.sql
  8. +0
    -0
      migrations/sqlite/20200809180000_create_form/up.sql
  9. +6
    -1
      src/account.rs
  10. +4
    -7
      src/database/methods.rs
  11. +40
    -29
      src/forward.rs
  12. +1
    -3
      src/sniff.rs

+ 7
- 1
Cargo.toml View File

@ -4,11 +4,17 @@ version = "1.0.0"
authors = ["Association 42l <contact@noreply.example.org>"]
edition = "2018"
[features]
default = [ "diesel/postgres" ]
postgres = [ "diesel/postgres" ]
mysql = [ "diesel/mysql" ]
sqlite = [ "diesel/sqlite" ]
[dependencies]
actix-rt = "1.0.0"
actix-web = "3.0.2"
actix-files = "0.3.0"
diesel = { version = "1.4", features = ["sqlite", "r2d2", "chrono"] }
diesel = { version = "1.4", features = ["r2d2", "chrono"] }
diesel_migrations = "1.4"
url = "2.1"
toml = "0.5"


+ 3
- 1
config.toml.sample View File

@ -6,7 +6,9 @@ listening_port = 8000
# includes protocol, FQDN and port, without the trailing slash.
sncf_url = "http://localhost:8000"
# path to the SQLite DB
# SQLite: path to the SQLite DB
# PostgreSQL: postgres://user:password@address:port/database
# MySQL: mysql://user:password@address:port/database
database_path = "./db/sncf.sqlite"
# IP address of the Nextcloud instance, including protocol and port


migrations/20200809180000_create_form/down.sql → migrations/mysql/20200809180000_create_form/down.sql View File


+ 8
- 0
migrations/mysql/20200809180000_create_form/up.sql View File

@ -0,0 +1,8 @@
CREATE TABLE form (
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT UNIQUE,
created_at TIMESTAMP NOT NULL,
lastvisit_at TIMESTAMP NOT NULL,
token VARCHAR(128) NOT NULL UNIQUE,
nc_username VARCHAR(128) NOT NULL UNIQUE,
nc_password VARCHAR(128) NOT NULL
);

+ 1
- 0
migrations/postgres/20200809180000_create_form/down.sql View File

@ -0,0 +1 @@
DELETE TABLE form;

+ 8
- 0
migrations/postgres/20200809180000_create_form/up.sql View File

@ -0,0 +1,8 @@
CREATE TABLE form (
id serial4 PRIMARY KEY UNIQUE NOT NULL,
created_at TIMESTAMP NOT NULL,
lastvisit_at TIMESTAMP NOT NULL,
token VARCHAR UNIQUE NOT NULL,
nc_username VARCHAR UNIQUE NOT NULL,
nc_password VARCHAR NOT NULL
);

+ 1
- 0
migrations/sqlite/20200809180000_create_form/down.sql View File

@ -0,0 +1 @@
DELETE TABLE form;

migrations/20200809180000_create_form/up.sql → migrations/sqlite/20200809180000_create_form/up.sql View File


+ 6
- 1
src/account.rs View File

@ -264,7 +264,12 @@ pub fn gen_name() -> String {
// uppercasing gen_token because NC would probably refuse two
// users with the same name but a different case
// and that'd be a pain to debug
format!("{}{}-{}", list_rand(&ADJ_LIST), list_rand(&NAME_LIST), gen_token(4).to_uppercase())
format!(
"{}{}-{}",
list_rand(&ADJ_LIST),
list_rand(&NAME_LIST),
gen_token(4).to_uppercase()
)
}
pub fn list_rand(list: &[String]) -> &String {


+ 4
- 7
src/database/methods.rs View File

@ -5,7 +5,7 @@ use diesel::prelude::*;
use crate::database::schema::form;
use crate::database::schema::form::dsl::*;
use crate::database::structs::Form;
use crate::SqliteConnection;
use crate::DbConn;
#[table_name = "form"]
#[derive(Serialize, Insertable)]
@ -22,7 +22,7 @@ impl Form {
// also updates lastvisit_at.
pub fn get_from_token(
i_token: &str,
conn: &SqliteConnection,
conn: &DbConn,
) -> Result<Option<Form>, diesel::result::Error> {
if let Some(formdata) = form
.filter(token.eq(i_token))
@ -38,10 +38,7 @@ impl Form {
}
}
pub fn update_lastvisit(
&self,
conn: &SqliteConnection,
) -> Result<usize, diesel::result::Error> {
pub fn update_lastvisit(&self, conn: &DbConn) -> Result<usize, diesel::result::Error> {
diesel::update(form.find(self.id))
.set(lastvisit_at.eq(Utc::now().naive_utc()))
.execute(conn)
@ -49,7 +46,7 @@ impl Form {
pub fn insert<'b>(
i_form: InsertableForm<'b>,
conn: &SqliteConnection,
conn: &DbConn,
) -> Result<InsertableForm<'b>, diesel::result::Error> {
match diesel::insert_into(form).values(&i_form).execute(conn) {
Ok(_) => Ok(i_form),


+ 40
- 29
src/forward.rs View File

@ -66,7 +66,7 @@ pub async fn forward(
{
client_resp.header(header_name.clone(), header_value.clone());
}
// sparing the use of a mutable body when not needed
// For now, the body only needs to be modified when the route
// is "create a new form" route
@ -90,9 +90,14 @@ pub async fn forward(
r#"{{"id":{},"keyValuePairs":{{"isAnonymous":true}}}}"#,
form_id
);
let update_req = forge_from("/ocs/v2.php/apps/forms/api/v1/form/update", &req, &url, &client)
.set_header("content-length", forged_body.len())
.set_header("content-type", "application/json;charset=utf-8");
let update_req = forge_from(
"/ocs/v2.php/apps/forms/api/v1/form/update",
&req,
&url,
&client,
)
.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);
@ -104,15 +109,15 @@ pub async fn forward(
eprintln!("error_forward_clientresp_newform: {}", e);
crash(get_lang(&req), "error_forward_clientresp_newform")
})?)
}
else {
Ok(client_resp.body(res.body().limit(PAYLOAD_LIMIT).await.map_err(|e| {
eprintln!("error_forward_clientresp_newform: {}", e);
crash(get_lang(&req), "error_forward_clientresp_std")
})?))
} else {
Ok(
client_resp.body(res.body().limit(PAYLOAD_LIMIT).await.map_err(|e| {
eprintln!("error_forward_clientresp_newform: {}", e);
crash(get_lang(&req), "error_forward_clientresp_std")
})?),
)
}
// check the response before returning it (unused)
/*if check_response(route, &response_body) {
return Ok(web_redir("/"));
@ -202,14 +207,14 @@ pub async fn forward_register(
.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)
).await.map_err(|e| {
eprintln!("error_redirect (admin): {}", e);
crash(get_lang(&req), "error_redirect")
})?);
return Ok(
web_redir(&format!("{}/admin/{}", CONFIG.sncf_url, &admin_token))
.await
.map_err(|e| {
eprintln!("error_redirect (admin): {}", e);
crash(get_lang(&req), "error_redirect")
})?,
);
} else {
debug("Incorrect admin token given in cookies.");
debug(&format!("Token: {:#?}", &admin_token));
@ -265,7 +270,9 @@ pub async fn forward_register(
eprintln!("error_tplrender (TplLink): {}", e);
crash(lang.clone(), "error_tplrender")
})?,
).await.map_err(|e| {
)
.await
.map_err(|e| {
eprintln!("error_tplrender_resp (TplLink): {}", e);
crash(lang, "error_tplrender_resp")
})?)
@ -304,16 +311,20 @@ 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()
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")
})?,
)
.await
.map_err(|e| {
eprintln!("error_tplrender (TplIndex): {}", e);
crash(get_lang(&req), "error_tplrender")
})?,
).await.map_err(|e| {
eprintln!("error_tplrender_resp (TplIndex): {}", e);
crash(get_lang(&req), "error_tplrender_resp")
})?)


+ 1
- 3
src/sniff.rs View File

@ -72,9 +72,7 @@ const BLOCKED_ROUTES: &[&str] = &[
];
// ...except if they are in this list
const ALLOWED_ROUTES: &[&str] = &[
"/ocs/v2.php/apps/forms/",
];
const ALLOWED_ROUTES: &[&str] = &["/ocs/v2.php/apps/forms/"];
// checks if the accessed route is allowed for the user.
// if it returns true, redirects elsewhere


Loading…
Cancel
Save