restructure files
|
@ -2,7 +2,10 @@
|
|||
address = "0.0.0.0"
|
||||
port = 8080
|
||||
template_dir = "dist/templates"
|
||||
state_dir = "dist"
|
||||
assets_dir = "dist/assets"
|
||||
keys_dir = "dist/keys"
|
||||
state_dir = "dist/hagrid_state"
|
||||
tmp_dir = "dist/tmp"
|
||||
|
||||
[development]
|
||||
base-URI = "http://localhost:8080"
|
||||
|
|
|
@ -19,10 +19,12 @@ use Result;
|
|||
pub struct Filesystem {
|
||||
update_lock: FlockMutex,
|
||||
|
||||
base: PathBuf,
|
||||
base_by_keyid: PathBuf,
|
||||
base_by_fingerprint: PathBuf,
|
||||
base_by_email: PathBuf,
|
||||
state_dir: PathBuf,
|
||||
tmp_dir: PathBuf,
|
||||
|
||||
keys_dir_by_keyid: PathBuf,
|
||||
keys_dir_by_fingerprint: PathBuf,
|
||||
keys_dir_by_email: PathBuf,
|
||||
}
|
||||
|
||||
/// Returns the given path, ensuring that the parent directory exists.
|
||||
|
@ -37,68 +39,89 @@ fn ensure_parent(path: &Path) -> Result<&Path> {
|
|||
|
||||
|
||||
impl Filesystem {
|
||||
pub fn new<P: Into<PathBuf>>(base: P) -> Result<Self> {
|
||||
pub fn new_from_base(base_dir: impl Into<PathBuf>) -> Result<Self> {
|
||||
let base_dir: PathBuf = base_dir.into();
|
||||
|
||||
let keys_dir = base_dir.join("keys");
|
||||
let state_dir = base_dir.join("hagrid_state");
|
||||
let tmp_dir = base_dir.join("tmp");
|
||||
|
||||
Self::new(keys_dir, state_dir, tmp_dir)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
keys_dir: impl Into<PathBuf>,
|
||||
state_dir: impl Into<PathBuf>,
|
||||
tmp_dir: impl Into<PathBuf>,
|
||||
) -> Result<Self> {
|
||||
use std::fs;
|
||||
|
||||
let base: PathBuf = base.into();
|
||||
let state_dir = state_dir.into();
|
||||
|
||||
if fs::create_dir(&base).is_err() {
|
||||
let meta = fs::metadata(&base);
|
||||
if fs::create_dir(&state_dir).is_err() {
|
||||
let meta = fs::metadata(&state_dir);
|
||||
|
||||
match meta {
|
||||
Ok(meta) => {
|
||||
if !meta.file_type().is_dir() {
|
||||
return Err(failure::format_err!(
|
||||
"'{}' exists already and is not a directory",
|
||||
base.display()));
|
||||
state_dir.display()));
|
||||
}
|
||||
|
||||
if meta.permissions().readonly() {
|
||||
return Err(failure::format_err!(
|
||||
"Cannot write '{}'",
|
||||
base.display()));
|
||||
state_dir.display()));
|
||||
}
|
||||
}
|
||||
|
||||
Err(e) => {
|
||||
return Err(failure::format_err!(
|
||||
"Cannot read '{}': {}",
|
||||
base.display(), e));
|
||||
state_dir.display(), e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create directories
|
||||
create_dir_all(base.join("verification_tokens"))?;
|
||||
create_dir_all(base.join("scratch_pad"))?;
|
||||
let tmp_dir = tmp_dir.into();
|
||||
create_dir_all(&tmp_dir)?;
|
||||
|
||||
let base_by_keyid = base.join("public").join("by-keyid");
|
||||
let base_by_fingerprint = base.join("public").join("by-fpr");
|
||||
let base_by_email = base.join("public").join("by-email");
|
||||
create_dir_all(&base_by_keyid)?;
|
||||
create_dir_all(&base_by_fingerprint)?;
|
||||
create_dir_all(&base_by_email)?;
|
||||
let token_dir = state_dir.join("verification_tokens");
|
||||
create_dir_all(token_dir)?;
|
||||
|
||||
info!("Opened base dir '{}'", base.display());
|
||||
let keys_dir: PathBuf = keys_dir.into();
|
||||
let keys_dir_by_keyid = keys_dir.join("by-keyid");
|
||||
let keys_dir_by_fingerprint = keys_dir.join("by-fpr");
|
||||
let keys_dir_by_email = keys_dir.join("by-email");
|
||||
create_dir_all(&keys_dir_by_keyid)?;
|
||||
create_dir_all(&keys_dir_by_fingerprint)?;
|
||||
create_dir_all(&keys_dir_by_email)?;
|
||||
|
||||
info!("Opened filesystem database.");
|
||||
info!("keys_dir: '{}'", keys_dir.display());
|
||||
info!("state_dir: '{}'", state_dir.display());
|
||||
info!("tmp_dir: '{}'", tmp_dir.display());
|
||||
Ok(Filesystem {
|
||||
update_lock: FlockMutex::new(&base)?,
|
||||
base: base,
|
||||
base_by_keyid: base_by_keyid,
|
||||
base_by_fingerprint: base_by_fingerprint,
|
||||
base_by_email: base_by_email,
|
||||
update_lock: FlockMutex::new(&state_dir)?,
|
||||
state_dir: state_dir,
|
||||
tmp_dir: tmp_dir,
|
||||
keys_dir_by_keyid: keys_dir_by_keyid,
|
||||
keys_dir_by_fingerprint: keys_dir_by_fingerprint,
|
||||
keys_dir_by_email: keys_dir_by_email,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the path to the given KeyID.
|
||||
fn keyid_to_path(&self, keyid: &KeyID) -> PathBuf {
|
||||
let hex = keyid.to_string();
|
||||
self.base_by_keyid.join(&hex[..2]).join(&hex[2..])
|
||||
self.keys_dir_by_keyid.join(&hex[..2]).join(&hex[2..])
|
||||
}
|
||||
|
||||
/// Returns the path to the given Fingerprint.
|
||||
fn fingerprint_to_path(&self, fingerprint: &Fingerprint) -> PathBuf {
|
||||
let hex = fingerprint.to_string();
|
||||
self.base_by_fingerprint.join(&hex[..2]).join(&hex[2..])
|
||||
self.keys_dir_by_fingerprint.join(&hex[..2]).join(&hex[2..])
|
||||
}
|
||||
|
||||
/// Returns the path to the given Email.
|
||||
|
@ -107,9 +130,9 @@ impl Filesystem {
|
|||
url::form_urlencoded::byte_serialize(email.as_str().as_bytes())
|
||||
.collect::<String>();
|
||||
if email.len() > 2 {
|
||||
self.base_by_email.join(&email[..2]).join(&email[2..])
|
||||
self.keys_dir_by_email.join(&email[..2]).join(&email[2..])
|
||||
} else {
|
||||
self.base_by_email.join(email)
|
||||
self.keys_dir_by_email.join(email)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +201,7 @@ impl Filesystem {
|
|||
Email::from_str(&decoded).ok()
|
||||
}
|
||||
|
||||
fn new_token<'a>(&self, base: &'a str) -> Result<(File, String)> {
|
||||
fn new_token<'a>(&self, token_type: &'a str) -> Result<(File, String)> {
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
||||
|
@ -186,16 +209,16 @@ impl Filesystem {
|
|||
// samples from [a-zA-Z0-9]
|
||||
// 43 chars ~ 256 bit
|
||||
let name: String = rng.sample_iter(&Alphanumeric).take(43).collect();
|
||||
let dir = self.base.join(base);
|
||||
let dir = self.state_dir.join(token_type);
|
||||
let fd = File::create(dir.join(&name))?;
|
||||
|
||||
Ok((fd, name))
|
||||
}
|
||||
|
||||
fn pop_token<'a>(
|
||||
&self, base: &'a str, token: &'a str,
|
||||
&self, token_type: &'a str, token: &'a str,
|
||||
) -> Result<Box<[u8]>> {
|
||||
let path = self.base.join(base).join(token);
|
||||
let path = self.state_dir.join(token_type).join(token);
|
||||
let buf = {
|
||||
let mut fd = File::open(&path)?;
|
||||
let mut buf = Vec::default();
|
||||
|
@ -221,7 +244,7 @@ impl Filesystem {
|
|||
let mut tpks = HashMap::new();
|
||||
|
||||
// Check Fingerprints.
|
||||
for entry in fs::read_dir(&self.base_by_fingerprint)? {
|
||||
for entry in fs::read_dir(&self.keys_dir_by_fingerprint)? {
|
||||
let prefix = entry?;
|
||||
let prefix_path = prefix.path();
|
||||
if ! prefix_path.is_dir() {
|
||||
|
@ -293,7 +316,7 @@ impl Filesystem {
|
|||
}
|
||||
|
||||
// Check KeyIDs.
|
||||
for entry in fs::read_dir(&self.base_by_keyid)? {
|
||||
for entry in fs::read_dir(&self.keys_dir_by_keyid)? {
|
||||
let prefix = entry?;
|
||||
let prefix_path = prefix.path();
|
||||
if ! prefix_path.is_dir() {
|
||||
|
@ -344,7 +367,7 @@ impl Filesystem {
|
|||
}
|
||||
|
||||
// Check Emails.
|
||||
for entry in fs::read_dir(&self.base_by_email)? {
|
||||
for entry in fs::read_dir(&self.keys_dir_by_email)? {
|
||||
let prefix = entry?;
|
||||
let prefix_path = prefix.path();
|
||||
if ! prefix_path.is_dir() {
|
||||
|
@ -431,14 +454,13 @@ impl Database for Filesystem {
|
|||
&self, fpr: &Fingerprint, new: Option<String>,
|
||||
) -> Result<()> {
|
||||
let target = self.fingerprint_to_path(fpr);
|
||||
let dir = self.base.join("scratch_pad");
|
||||
|
||||
match new {
|
||||
Some(new) => {
|
||||
let mut tmp = tempfile::Builder::new()
|
||||
.prefix("key")
|
||||
.rand_bytes(16)
|
||||
.tempfile_in(dir)?;
|
||||
.tempfile_in(&self.tmp_dir)?;
|
||||
|
||||
tmp.write_all(new.as_bytes()).unwrap();
|
||||
let _ = tmp.persist(ensure_parent(&target)?)?;
|
||||
|
@ -505,7 +527,7 @@ impl Database for Filesystem {
|
|||
};
|
||||
|
||||
if path.exists() {
|
||||
Some(diff_paths(&path, &self.base).expect("related paths"))
|
||||
Some(diff_paths(&path, &self.state_dir).expect("related paths"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -786,7 +808,7 @@ mod tests {
|
|||
// same two nibble prefix.
|
||||
assert_eq!(
|
||||
db.path_to_fingerprint_base(
|
||||
&db.base_by_fingerprint.join("CB"),
|
||||
&db.keys_dir_by_fingerprint.join("CB"),
|
||||
&PathBuf::from("CD8F030588653EEDD7E2659B7DD433F254904A")),
|
||||
Some(fp));
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.45"
|
||||
width="70"
|
||||
height="92"
|
||||
version="1.0"
|
||||
sodipodi:docbase="D:\Desktop"
|
||||
sodipodi:docname="GnuPG-Logo.png"
|
||||
sodipodi:modified="true">
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs5" />
|
||||
<sodipodi:namedview
|
||||
inkscape:window-height="975"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
width="70px"
|
||||
height="92px"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="37.678772"
|
||||
inkscape:cy="50.578436"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="-4"
|
||||
inkscape:current-layer="svg2" />
|
||||
<rect
|
||||
style="opacity:1;fill:#0093dd;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect3132"
|
||||
width="70"
|
||||
height="47.099998"
|
||||
x="0"
|
||||
y="44.900002" />
|
||||
<rect
|
||||
style="opacity:1;fill:#0093dd;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4103"
|
||||
width="15.009007"
|
||||
height="19.485378"
|
||||
x="4.7396865"
|
||||
y="25.468845" />
|
||||
<rect
|
||||
style="opacity:1;fill:#0093dd;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4105"
|
||||
width="15.18455"
|
||||
height="19.239996"
|
||||
x="50.117794"
|
||||
y="25.694933" />
|
||||
<path
|
||||
style="opacity:1;fill:#0093dd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 35.625,0 C 13.155955,0.16164779 4.75,20.998357 4.75,25.5625 C 10.896546,25.562499 17.561658,25.90625 18.96875,25.90625 C 19.298759,25.90625 19.367598,25.906322 19.6875,25.90625 C 21.365862,19.035999 27.552617,13.9375 34.9375,13.9375 C 42.289526,13.9375 48.445364,18.988532 50.15625,25.8125 C 50.543323,25.812313 50.720292,25.8125 51.125,25.8125 C 63.764162,25.8125 65.25,25.90625 65.25,25.90625 C 65.25,25.90625 60.201152,-0.17554394 35.625,0 z "
|
||||
id="path6045" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
|
||||
d="M 10.269321,25.20553 C 21.691029,1.9172856 37.700972,5.1573508 46.958242,6.5921309 C 46.958242,6.5921309 34.785164,0.76242296 23.084029,6.5100997 C 11.608567,12.146925 10.269321,25.20553 10.269321,25.20553 z "
|
||||
id="path7026"
|
||||
sodipodi:nodetypes="ccsc" />
|
||||
<path
|
||||
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1"
|
||||
d="M -0.25,68.25 C -0.25,68.25 7.5390098,59.548683 13.8125,57.25 C 22,54.25 32,55.1875 48.5625,51.875 C 54.425075,50.702485 56.25,49.25 65.1875,44.625 C 65.942492,44.234305 70.5625,44.3125 70.5625,44.3125 L 70.1875,50.5625 C 60,61.25 36.75,67.21875 34.8125,67.125 C 54.479984,69.763423 64.97809,59.568082 69.25,58.9375 C 59.3125,80.0625 24.0625,79 24.0625,79 C 44.5,84.5625 61.125,76.25 61.125,76.25 C 51.8125,91.65625 17.4375,89.5625 17.4375,89.5625 C 13.84375,89.875 10.9375,92.1875 10.9375,92.1875 L -0.125,92.5 L -0.25,68.25 z "
|
||||
id="path7997"
|
||||
sodipodi:nodetypes="cssscccccccccc" />
|
||||
</svg>
|
After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
@ -51,7 +51,7 @@ fn main() {
|
|||
|
||||
fn real_main() -> Result<()> {
|
||||
let opt = Opt::from_args();
|
||||
let db = Filesystem::new(opt.base.canonicalize()?)?;
|
||||
let db = Filesystem::new_from_base(opt.base.canonicalize()?)?;
|
||||
delete(&db, &opt.query.parse()?, opt.all_bindings, opt.all)
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ fn main() {
|
|||
}
|
||||
|
||||
fn do_import(base: PathBuf, keyrings: Vec<PathBuf>) -> Result<()> {
|
||||
let db = Filesystem::new(base)?;
|
||||
let db = Filesystem::new_from_base(base)?;
|
||||
|
||||
// For each input file, create a parser.
|
||||
for input in keyrings.iter() {
|
||||
|
@ -110,7 +110,7 @@ mod import_tests {
|
|||
fn import() {
|
||||
let root = tempdir().unwrap();
|
||||
|
||||
let db = Filesystem::new(root.path().to_path_buf()).unwrap();
|
||||
let db = Filesystem::new_from_base(root.path().to_path_buf()).unwrap();
|
||||
|
||||
// Generate a key and import it.
|
||||
let (tpk, _) = openpgp::tpk::TPKBuilder::autocrypt(
|
||||
|
|
117
src/web/mod.rs
|
@ -1,6 +1,7 @@
|
|||
use rocket;
|
||||
use rocket::http::Header;
|
||||
use rocket::response::NamedFile;
|
||||
use rocket::config::Config;
|
||||
use rocket_contrib::templates::Template;
|
||||
|
||||
use serde::Serialize;
|
||||
|
@ -65,6 +66,7 @@ impl MyResponse {
|
|||
})
|
||||
}
|
||||
|
||||
// XXX needs fixing for keys_dir!
|
||||
pub fn x_accel_redirect(path: PathBuf, fp: &Fingerprint) -> Self {
|
||||
use rocket::http::hyper::header::{ContentDisposition, DispositionType,
|
||||
DispositionParam, Charset};
|
||||
|
@ -170,13 +172,14 @@ mod templates {
|
|||
}
|
||||
|
||||
pub struct HagridState {
|
||||
/// The base directory.
|
||||
/// State directory, used internally by hagrid
|
||||
state_dir: PathBuf,
|
||||
|
||||
/// The public directory.
|
||||
///
|
||||
/// This is what nginx serves.
|
||||
public_dir: PathBuf,
|
||||
/// Assets directory, mounted to /assets, served by hagrid or nginx
|
||||
assets_dir: PathBuf,
|
||||
|
||||
/// The keys directory, where keys are located, served by hagrid or nginx
|
||||
keys_dir: PathBuf,
|
||||
|
||||
/// XXX
|
||||
base_uri: String,
|
||||
|
@ -307,7 +310,7 @@ fn publish_verify(db: rocket::State<Polymorphic>,
|
|||
|
||||
#[get("/assets/<file..>")]
|
||||
fn files(file: PathBuf, state: rocket::State<HagridState>) -> Option<NamedFile> {
|
||||
NamedFile::open(state.public_dir.join("assets").join(file)).ok()
|
||||
NamedFile::open(state.assets_dir.join(file)).ok()
|
||||
}
|
||||
|
||||
#[get("/")]
|
||||
|
@ -335,8 +338,6 @@ pub fn serve() -> Result<()> {
|
|||
}
|
||||
|
||||
fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let routes = routes![
|
||||
// infra
|
||||
root,
|
||||
|
@ -362,25 +363,62 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
manage::vks_manage_unpublish,
|
||||
];
|
||||
|
||||
let db_service = configure_db_service(rocket.config())?;
|
||||
let hagrid_state = configure_hagrid_state(rocket.config())?;
|
||||
let token_service = configure_token_service(rocket.config())?;
|
||||
let mail_service = configure_mail_service(rocket.config())?;
|
||||
|
||||
Ok(rocket
|
||||
.attach(Template::fairing())
|
||||
.manage(hagrid_state)
|
||||
.manage(token_service)
|
||||
.manage(mail_service)
|
||||
.manage(db_service)
|
||||
.mount("/", routes)
|
||||
)
|
||||
}
|
||||
|
||||
fn configure_db_service(config: &Config) -> Result<Polymorphic> {
|
||||
use database::{Filesystem, Polymorphic};
|
||||
let db = Polymorphic::Filesystem(
|
||||
Filesystem::new(&PathBuf::from(rocket.config().get_str("state_dir")?))?
|
||||
);
|
||||
|
||||
let keys_dir: PathBuf = config.get_str("keys_dir")?.into();
|
||||
let state_dir: PathBuf = config.get_str("state_dir")?.into();
|
||||
let tmp_dir: PathBuf = config.get_str("tmp_dir")?.into();
|
||||
|
||||
let fs_db = Filesystem::new(keys_dir, state_dir, tmp_dir)?;
|
||||
Ok(Polymorphic::Filesystem(fs_db))
|
||||
}
|
||||
|
||||
fn configure_hagrid_state(config: &Config) -> Result<HagridState> {
|
||||
let state_dir: PathBuf = config.get_str("state_dir")?.into();
|
||||
let assets_dir: PathBuf = config.get_str("assets_dir")?.into();
|
||||
let keys_dir: PathBuf = config.get_str("keys_dir")?.into();
|
||||
|
||||
// State
|
||||
let state_dir: PathBuf = rocket.config().get_str("state_dir")?.into();
|
||||
let public_dir = state_dir.join("public");
|
||||
let base_uri = rocket.config().get_str("base-URI")?.to_string();
|
||||
let state = HagridState {
|
||||
state_dir: state_dir,
|
||||
public_dir: public_dir,
|
||||
let base_uri = config.get_str("base-URI")?.to_string();
|
||||
Ok(HagridState {
|
||||
state_dir,
|
||||
assets_dir,
|
||||
keys_dir,
|
||||
base_uri: base_uri.clone(),
|
||||
x_accel_redirect: rocket.config().get_bool("x-accel-redirect")?,
|
||||
};
|
||||
x_accel_redirect: config.get_bool("x-accel-redirect")?,
|
||||
})
|
||||
}
|
||||
|
||||
fn configure_token_service(config: &Config) -> Result<tokens::Service> {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let secret = config.get_str("token_secret")?.to_string();
|
||||
let validity = config.get_int("token_validity")?;
|
||||
let validity = u64::try_from(validity)?;
|
||||
Ok(tokens::Service::init(&secret, validity))
|
||||
}
|
||||
|
||||
fn configure_mail_service(config: &Config) -> Result<mail::Service> {
|
||||
// Mail service
|
||||
let template_dir: PathBuf = rocket.config().get_str("template_dir")?.into();
|
||||
let from = rocket.config().get_str("from")?.to_string();
|
||||
let template_dir: PathBuf = config.get_str("template_dir")?.into();
|
||||
let base_uri = config.get_str("base-URI")?.to_string();
|
||||
let from = config.get_str("from")?.to_string();
|
||||
let verify_html = template_dir.join("email/publish-html.hbs");
|
||||
let verify_txt = template_dir.join("email/publish-txt.hbs");
|
||||
let manage_html = template_dir.join("email/manage-html.hbs");
|
||||
|
@ -392,26 +430,14 @@ fn rocket_factory(rocket: rocket::Rocket) -> Result<rocket::Rocket> {
|
|||
handlebars.register_template_file("manage-html", manage_html)?;
|
||||
handlebars.register_template_file("manage-txt", manage_txt)?;
|
||||
|
||||
let filemail_into = rocket.config().get_str("filemail_into")
|
||||
let filemail_into = config.get_str("filemail_into")
|
||||
.ok().map(|p| PathBuf::from(p));
|
||||
let mail_service = if let Some(path) = filemail_into {
|
||||
mail::Service::filemail(from, base_uri, handlebars, path)?
|
||||
|
||||
if let Some(path) = filemail_into {
|
||||
mail::Service::filemail(from, base_uri, handlebars, path)
|
||||
} else {
|
||||
mail::Service::sendmail(from, base_uri, handlebars)?
|
||||
};
|
||||
|
||||
let secret = rocket.config().get_str("token_secret")?.to_string();
|
||||
let validity = rocket.config().get_int("token_validity")?;
|
||||
let validity = u64::try_from(validity)?;
|
||||
let token_service = tokens::Service::init(&secret, validity);
|
||||
|
||||
Ok(rocket
|
||||
.attach(Template::fairing())
|
||||
.manage(state)
|
||||
.manage(mail_service)
|
||||
.manage(token_service)
|
||||
.mount("/", routes)
|
||||
.manage(db))
|
||||
mail::Service::sendmail(from, base_uri, handlebars)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -449,16 +475,19 @@ pub mod tests {
|
|||
let filemail = root.path().join("filemail");
|
||||
::std::fs::create_dir_all(&filemail)?;
|
||||
|
||||
let base_dir: PathBuf = root.path().into();
|
||||
|
||||
let config = Config::build(Environment::Staging)
|
||||
.root(root.path().to_path_buf())
|
||||
.extra("template_dir",
|
||||
::std::env::current_dir().unwrap().join("dist/templates")
|
||||
.to_str().unwrap())
|
||||
.extra(
|
||||
"state_dir",
|
||||
root.path().to_str()
|
||||
.ok_or(failure::err_msg("Static path invalid"))?,
|
||||
)
|
||||
.extra("assets_dir",
|
||||
::std::env::current_dir().unwrap().join("dist/assets")
|
||||
.to_str().unwrap())
|
||||
.extra("keys_dir", base_dir.join("keys").to_str().unwrap())
|
||||
.extra("tmp_dir", base_dir.join("tmp").to_str().unwrap())
|
||||
.extra("state_dir", base_dir.join("state").to_str().unwrap())
|
||||
.extra("base-URI", BASE_URI)
|
||||
.extra("from", "from")
|
||||
.extra("token_secret", "hagrid")
|
||||
|
|