Simplify domain handling.

This commit is contained in:
Justus Winter 2019-03-13 09:56:33 +01:00
parent 1f2471ba61
commit 30c3b66b4f
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
4 changed files with 32 additions and 33 deletions

View File

@ -29,6 +29,7 @@ mod context {
pub struct Service { pub struct Service {
from: String, from: String,
domain: String,
templates: Handlebars, templates: Handlebars,
transport: Transport, transport: Transport,
} }
@ -40,33 +41,36 @@ enum Transport {
impl Service { impl Service {
/// Sends mail via sendmail. /// Sends mail via sendmail.
pub fn sendmail(from: String, templates: Handlebars) -> Self { pub fn sendmail(from: String, domain: String, templates: Handlebars) -> Self {
Self { Self {
from: from, from: from,
domain: domain,
templates: templates, templates: templates,
transport: Transport::Sendmail, transport: Transport::Sendmail,
} }
} }
/// Sends mail by storing it in the given directory. /// Sends mail by storing it in the given directory.
pub fn filemail(from: String, templates: Handlebars, path: PathBuf) pub fn filemail(from: String, domain: String, templates: Handlebars,
path: PathBuf)
-> Self -> Self
{ {
Self { Self {
from: from, from: from,
domain: domain,
templates: templates, templates: templates,
transport: Transport::Filemail(path), transport: Transport::Filemail(path),
} }
} }
pub fn send_verification(&self, tpk: &openpgp::TPK, userid: &Email, pub fn send_verification(&self, tpk: &openpgp::TPK, userid: &Email,
token: &str, domain: &str) token: &str)
-> Result<()> { -> Result<()> {
let ctx = context::Verification { let ctx = context::Verification {
primary_fp: tpk.fingerprint().to_string(), primary_fp: tpk.fingerprint().to_string(),
uri: format!("https://{}/publish/{}", domain, token), uri: format!("https://{}/publish/{}", self.domain, token),
userid: userid.to_string(), userid: userid.to_string(),
domain: domain.to_string(), domain: self.domain.clone(),
}; };
self.send( self.send(
@ -77,12 +81,11 @@ impl Service {
) )
} }
pub fn send_confirmation(&self, userids: &[Email], token: &str, pub fn send_confirmation(&self, userids: &[Email], token: &str)
domain: &str)
-> Result<()> { -> Result<()> {
let ctx = context::Deletion { let ctx = context::Deletion {
uri: format!("https://{}/delete/{}", domain, token), uri: format!("https://{}/delete/{}", self.domain, token),
domain: domain.to_string(), domain: self.domain.clone(),
}; };
self.send( self.send(

View File

@ -107,10 +107,10 @@ impl<'a, 'r> FromRequest<'a, 'r> for Hkp {
} }
#[post("/pks/add", data = "<data>")] #[post("/pks/add", data = "<data>")]
pub fn pks_add(db: rocket::State<Polymorphic>, cont_type: &ContentType, data: Data, pub fn pks_add(db: rocket::State<Polymorphic>, cont_type: &ContentType,
state: rocket::State<State>) data: Data)
-> MyResponse { -> MyResponse {
match upload::handle_upload(db, cont_type, data, None, state) { match upload::handle_upload(db, cont_type, data, None) {
Ok(_) => MyResponse::plain("Ok".into()), Ok(_) => MyResponse::plain("Ok".into()),
Err(err) => MyResponse::ise(err), Err(err) => MyResponse::ise(err),
} }

View File

@ -336,8 +336,7 @@ struct ManageRequest {
} }
#[post("/delete", data="<request>")] #[post("/delete", data="<request>")]
fn delete_post(state: rocket::State<State>, fn delete_post(db: rocket::State<Polymorphic>,
db: rocket::State<Polymorphic>,
mail_service: rocket::State<mail::Service>, mail_service: rocket::State<mail::Service>,
request: Form<ManageRequest>) -> MyResponse { request: Form<ManageRequest>) -> MyResponse {
use std::convert::TryInto; use std::convert::TryInto;
@ -363,7 +362,7 @@ fn delete_post(state: rocket::State<State>,
}; };
if let Err(e) = mail_service.send_confirmation( if let Err(e) = mail_service.send_confirmation(
&uids, &token, &state.domain) { &uids, &token) {
return MyResponse::ise(e); return MyResponse::ise(e);
} }
@ -454,10 +453,11 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
// State // State
let state_dir: PathBuf = rocket.config().get_str("state_dir")?.into(); let state_dir: PathBuf = rocket.config().get_str("state_dir")?.into();
let public_dir = state_dir.join("public"); let public_dir = state_dir.join("public");
let domain = rocket.config().get_str("domain")?.to_string();
let state = State { let state = State {
state_dir: state_dir, state_dir: state_dir,
public_dir: public_dir, public_dir: public_dir,
domain: rocket.config().get_str("domain")?.to_string(), domain: domain.clone(),
x_accel_redirect: rocket.config().get_bool("x-accel-redirect")?, x_accel_redirect: rocket.config().get_bool("x-accel-redirect")?,
}; };
@ -478,9 +478,9 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
let filemail_into = rocket.config().get_str("filemail_into") let filemail_into = rocket.config().get_str("filemail_into")
.ok().map(|p| PathBuf::from(p)); .ok().map(|p| PathBuf::from(p));
let mail_service = if let Some(path) = filemail_into { let mail_service = if let Some(path) = filemail_into {
mail::Service::filemail(from, handlebars, path) mail::Service::filemail(from, domain, handlebars, path)
} else { } else {
mail::Service::sendmail(from, handlebars) mail::Service::sendmail(from, domain, handlebars)
}; };
Ok(rocket Ok(rocket

View File

@ -10,7 +10,7 @@ use rocket::Data;
use database::{Database, Polymorphic}; use database::{Database, Polymorphic};
use mail; use mail;
use web::{State, MyResponse}; use web::MyResponse;
use std::io::Read; use std::io::Read;
@ -39,9 +39,9 @@ pub fn publish() -> MyResponse {
#[post("/vks/v1/publish", data = "<data>")] #[post("/vks/v1/publish", data = "<data>")]
pub fn vks_v1_publish_post( pub fn vks_v1_publish_post(
db: rocket::State<Polymorphic>, cont_type: &ContentType, data: Data, db: rocket::State<Polymorphic>, cont_type: &ContentType, data: Data,
mail_service: rocket::State<mail::Service>, state: rocket::State<State>, mail_service: rocket::State<mail::Service>
) -> MyResponse { ) -> MyResponse {
match handle_upload(db, cont_type, data, Some(mail_service), state) { match handle_upload(db, cont_type, data, Some(mail_service)) {
Ok(ok) => ok, Ok(ok) => ok,
Err(err) => MyResponse::ise(err), Err(err) => MyResponse::ise(err),
} }
@ -50,7 +50,7 @@ pub fn vks_v1_publish_post(
// signature requires the request to have a `Content-Type` // signature requires the request to have a `Content-Type`
pub fn handle_upload( pub fn handle_upload(
db: rocket::State<Polymorphic>, cont_type: &ContentType, data: Data, db: rocket::State<Polymorphic>, cont_type: &ContentType, data: Data,
mail_service: Option<rocket::State<mail::Service>>, state: rocket::State<State>, mail_service: Option<rocket::State<mail::Service>>
) -> Result<MyResponse> { ) -> Result<MyResponse> {
if cont_type.is_form_data() { if cont_type.is_form_data() {
// multipart/form-data // multipart/form-data
@ -63,7 +63,7 @@ pub fn handle_upload(
boundary param not provided"))), boundary param not provided"))),
}; };
process_upload(boundary, data, db.inner(), mail_service, &state.domain) process_upload(boundary, data, db.inner(), mail_service)
} else if cont_type.is_form() { } else if cont_type.is_form() {
use rocket::request::FormItems; use rocket::request::FormItems;
use std::io::Cursor; use std::io::Cursor;
@ -87,7 +87,6 @@ pub fn handle_upload(
Cursor::new(decoded_value.as_bytes()), Cursor::new(decoded_value.as_bytes()),
&db, &db,
mail_service, mail_service,
&state.domain,
); );
} }
_ => { /* skip */ } _ => { /* skip */ }
@ -105,29 +104,28 @@ pub fn handle_upload(
fn process_upload( fn process_upload(
boundary: &str, data: Data, db: &Polymorphic, boundary: &str, data: Data, db: &Polymorphic,
mail_service: Option<rocket::State<mail::Service>>, mail_service: Option<rocket::State<mail::Service>>,
domain: &str,
) -> Result<MyResponse> { ) -> Result<MyResponse> {
// saves all fields, any field longer than 10kB goes to a temporary directory // saves all fields, any field longer than 10kB goes to a temporary directory
// Entries could implement FromData though that would give zero control over // Entries could implement FromData though that would give zero control over
// how the files are saved; Multipart would be a good impl candidate though // how the files are saved; Multipart would be a good impl candidate though
match Multipart::with_body(data.open().take(UPLOAD_LIMIT), boundary).save().temp() { match Multipart::with_body(data.open().take(UPLOAD_LIMIT), boundary).save().temp() {
Full(entries) => { Full(entries) => {
process_multipart(entries, db, mail_service, domain) process_multipart(entries, db, mail_service)
} }
Partial(partial, _) => { Partial(partial, _) => {
process_multipart(partial.entries, db, mail_service, domain) process_multipart(partial.entries, db, mail_service)
} }
Error(err) => Err(err.into()) Error(err) => Err(err.into())
} }
} }
fn process_multipart(entries: Entries, db: &Polymorphic, fn process_multipart(entries: Entries, db: &Polymorphic,
mail_service: Option<rocket::State<mail::Service>>, mail_service: Option<rocket::State<mail::Service>>)
domain: &str) -> Result<MyResponse> { -> Result<MyResponse> {
match entries.fields.get("keytext") { match entries.fields.get("keytext") {
Some(ent) if ent.len() == 1 => { Some(ent) if ent.len() == 1 => {
let reader = ent[0].data.readable()?; let reader = ent[0].data.readable()?;
process_key(reader, db, mail_service, domain) process_key(reader, db, mail_service)
} }
Some(_) => Some(_) =>
Ok(MyResponse::bad_request( Ok(MyResponse::bad_request(
@ -140,7 +138,6 @@ fn process_multipart(entries: Entries, db: &Polymorphic,
fn process_key<R>( fn process_key<R>(
reader: R, db: &Polymorphic, mail_service: Option<rocket::State<mail::Service>>, reader: R, db: &Polymorphic, mail_service: Option<rocket::State<mail::Service>>,
domain: &str,
) -> Result<MyResponse> ) -> Result<MyResponse>
where where
R: Read, R: Read,
@ -171,7 +168,6 @@ where
&tpk, &tpk,
&email, &email,
&token, &token,
domain,
)?; )?;
results.push(email.to_string()); results.push(email.to_string());
} }