From f8e04f96df65616fff89e7faac707f999176d18b Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Nov 2018 03:14:03 +0100 Subject: license: Generate a license and send it in HTTP response If the purchaser coming from POST params is found in the database, generate a license for the purchaser, zip the license, and send a response containing the zipped data. zip: Change the writer input to a mutable reference to enable us to use the zip data when writing to the response. Otherwise we get a borrow error. --- license-generator/src/bin/license.rs | 68 ++++++++++++++++++++++++++++++++---- license-generator/src/errors.rs | 1 + license-generator/src/zip.rs | 2 +- 3 files changed, 64 insertions(+), 7 deletions(-) (limited to 'license-generator/src') diff --git a/license-generator/src/bin/license.rs b/license-generator/src/bin/license.rs index 54552f1..777b206 100644 --- a/license-generator/src/bin/license.rs +++ b/license-generator/src/bin/license.rs @@ -1,21 +1,38 @@ ///! FastCGI script that displays a thank-you page with a link to download a ///! custom-generated license. +extern crate aquatic_prime; extern crate fastcgi; +extern crate exitcode; #[macro_use] extern crate log; +#[macro_use] +extern crate serde_derive; + extern crate license_generator; use std::borrow::Cow; -use std::io::{Read, Write}; +use std::io::{Cursor, Read, Write}; + +use aquatic_prime::AquaticPrime; use license_generator::database; use license_generator::errors::*; use license_generator::logger; use license_generator::params; use license_generator::response; +use license_generator::zip; + +#[derive(Serialize)] +struct LicenseData<'a> { + #[serde(rename = "Name")] + name: &'a str, + + #[serde(rename = "Email")] + email: &'a str, +} fn main() -> Result<()> { logger::init()?; @@ -30,6 +47,27 @@ fn main() -> Result<()> { }, }; + // TODO: Change to include_str! + let public_key = match std::str::from_utf8( + include_bytes!("../../private/public_key.txt") + ).chain_err(|| "public key could not be loaded") { + Ok(k) => k, + Err(e) => { + error!("{}", e); + return Err(e); + }, + }; + let private_key = match std::str::from_utf8( + include_bytes!("../../private/private_key.txt") + ).chain_err(|| "private key could not be loaded") { + Ok(k) => k, + Err(e) => { + error!("{}", e); + return Err(e); + }, + }; + let aquatic_prime = AquaticPrime::new(&public_key, &private_key); + fastcgi::run(move |mut req| { let mut params = String::new(); match req.stdin().read_to_string(&mut params) { @@ -72,8 +110,12 @@ fn main() -> Result<()> { let secret = ps.get("secret"); if name.is_some() && email.is_some() && secret.is_some() { + let name = name.unwrap().to_string(); + let email = email.unwrap().to_string(); + let secret = secret.unwrap().to_string(); + let mut tx = cx.start_transaction(false, None, None).unwrap(); - let query_result = tx.prep_exec(" + let row = tx.prep_exec(" SELECT id FROM purchasers WHERE name = ? @@ -82,13 +124,27 @@ fn main() -> Result<()> { AND secret = ?", ( - name.unwrap().to_string(), - email.unwrap().to_string(), - secret.unwrap().to_string(), + &name, + &email, + &secret, ) ).unwrap().next(); - info!("Row: {:?}", query_result); + if row.is_some() { + let license_data = LicenseData { + name: &name, + email: &email, + }; + + let license = aquatic_prime.plist(license_data).unwrap(); + + let mut zip_data = Cursor::new(vec![]); + zip::license(&mut zip_data, license.as_bytes()).unwrap(); + + write!(&mut req.stdout(), "Content-Type: application/zip\n\n") + .unwrap(); + req.stdout().write_all(&zip_data.into_inner()).unwrap(); + } tx.commit().unwrap(); } else { diff --git a/license-generator/src/errors.rs b/license-generator/src/errors.rs index c7aadc6..352f959 100644 --- a/license-generator/src/errors.rs +++ b/license-generator/src/errors.rs @@ -7,6 +7,7 @@ error_chain! { foreign_links { EnvVar(::std::env::VarError); Io(::std::io::Error); + Utf8(::std::string::FromUtf8Error); Log(log::SetLoggerError); MySql(mysql::error::Error); diff --git a/license-generator/src/zip.rs b/license-generator/src/zip.rs index 6c08368..7b3600c 100644 --- a/license-generator/src/zip.rs +++ b/license-generator/src/zip.rs @@ -4,7 +4,7 @@ use zip_lib as zip; use errors::*; -pub fn license(w: W, plist: &[u8]) -> Result<()> { +pub fn license(w: &mut W, plist: &[u8]) -> Result<()> { let mut zip = zip::ZipWriter::new(w); zip.start_file( -- cgit v1.2.3