Skip to content

Instantly share code, notes, and snippets.

@omac777
Created August 25, 2021 20:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omac777/dc8dbd9b4fe574e7e01ad6bf9a8ee9d7 to your computer and use it in GitHub Desktop.
Save omac777/dc8dbd9b4fe574e7e01ad6bf9a8ee9d7 to your computer and use it in GitHub Desktop.
tide tls basic auth structsy bootstrap hello
[package]
name = "tide-rustls"
version = "0.3.0"
authors = ["David Marceau <uticdmarceau2007@yahoo.ca>"]
edition = "2018"
description = "tide tls listener based on async-rustls and rustls"
readme = "README.md"
license = "MIT OR Apache-2.0"
keywords = ["tide", "https", "tls"]
categories = ["web-programming::http-server", "web-programming"]
[dependencies]
async-std = "1.9.0"
tide = { version = "0.16.0", default-features = false }
async-rustls = "0.2.0"
rustls = "0.19.0"
async-h1 = "2.3.2"
async-dup = "1.2.2"
tide-http-auth = "0.5.0"
async-trait = "0.1.41"
sailfish = "0.3.3"
sailfish-macros = "0.3.3"
structsy = "0.3.0"
structsy-derive="0.3.0"
use std::env;
use tide_rustls::TlsListener;
use tide_http_auth::{BasicAuthRequest, Storage};
use tide::http::mime;
use tide::Response;
use structsy::{Structsy, StructsyError, StructsyTx};
use structsy_derive::{queries, Persistent};
#[derive(Clone, Persistent, Debug, PartialEq)]
struct MyUser {
#[index(mode = "cluster")]
username: String,
favorite_food: String,
password: String,
}
#[queries(MyUser)]
trait MyUserQuery {
fn search(self, username: String) -> Self;
}
#[derive(Clone)]
struct ExampleState {
db : Structsy,
}
impl ExampleState {
pub fn new(db : Structsy) -> Self {
ExampleState { db }
}
}
#[async_trait::async_trait]
impl Storage<MyUser, BasicAuthRequest> for ExampleState {
async fn get_user(&self, request: BasicAuthRequest) -> tide::Result<Option<MyUser>> {
let to_find = &request.username.clone();
let mut iter = self.db.query::<MyUser>().search(to_find.clone()).into_iter();
let myuserdata = iter.next();
println!("search() found:<<{:?}>>", myuserdata);
match myuserdata {
//(structsy::Ref<MyUser>, MyUser)
Some((_theid, theuser)) => {
if theuser.password != request.password {
return Ok(None);
}
println!("search() found:<<{:?}>>", theuser);
Ok(Some(theuser.clone()))
}
None => Ok(None),
}
}
}
use sailfish::TemplateOnce;
#[derive(TemplateOnce)]
#[template(path = "/home/davidm/tryredox/tide-rustls/examples/templates/hello.stpl")]
struct HelloTemplate {
messages: Vec<String>,
currentusername: String,
currentfavfood: String,
}
async fn hello<State>(req: tide::Request<State>) -> tide::Result<tide::Response> {
if let Some(user) = req.ext::<MyUser>() {
let ctx = HelloTemplate {
messages: vec![String::from("foo"), String::from("bar")],
currentusername: user.username.clone(),
currentfavfood: user.favorite_food.clone(),
};
Ok(Response::builder(200)
.body(ctx.render_once().unwrap())
.content_type(mime::HTML).into())
} else {
let mut response: tide::Response = "Hello Unauthorized Guest lol".to_string().into();
response.set_status(tide::http::StatusCode::Unauthorized);
response.insert_header("WWW-Authenticate", "Basic");
Ok(response)
}
}
fn main() -> Result<(), StructsyError> {
async_std::task::block_on(async {
let port = env::var("PORT").ok().unwrap_or_else(|| "4433".to_string());
let host = env::var("HOST").ok().unwrap_or_else(|| "127.0.0.1".to_string());
let addr = format!("{}:{}", host, port);
let cert = env::var("TIDE_CERT").ok().unwrap_or_else(|| "/home/davidm/tryredox/davidmarceau.tk/zerosslCerts09July2021/rocketrsFullChain09July2021.crt".to_string());
let key = env::var("TIDE_KEY").ok().unwrap_or_else(|| "/home/davidm/tryredox/davidmarceau.tk/zerosslCerts09July2021/private.key".to_string());
let db : Structsy = Structsy::open("tide_structsy_users.db")?;
db.define::<MyUser>()?;
let my_data = MyUser {
username: "zach".to_string(),
favorite_food: "Kemptville food truck Cubano sandwich".to_string(),
password: "knox".to_string(),
};
let other_data = MyUser {
username: "spencer".to_string(),
favorite_food: "Lone Star french fries and donuts".to_string(),
password: "613218749poopy".to_string(),
};
let mut tx = db.begin()?;
let _id = tx.insert(&my_data)?;
let _id = tx.insert(&other_data)?;
tx.commit()?;
let mut app = tide::with_state(ExampleState::new(db));
app.with(tide_http_auth::Authentication::new(
tide_http_auth::BasicAuthScheme::default(),
));
app.at("/hello").get(hello);
//serve the following different bootstrap css/js files
//within authenticated handlers resembling the above hello
//serve_file is unauthenticated/insufficient
app.at("/cheatsheet/cheatsheet").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/cheatsheet/index.html")?;
app.at("/cheatsheet/cheatsheet.css").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/cheatsheet/cheatsheet.css")?;
app.at("/cheatsheet/cheatsheet.js").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/cheatsheet/cheatsheet.js")?;
app.at("/cheatsheet/cheatsheet.rtl.css").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/cheatsheet/cheatsheet.rtl.css")?;
app.at("/assets/dist/js/bootstrap.bundle.min.js").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/assets/dist/js/bootstrap.bundle.min.js")?;
app.at("/assets/img/favicons/favicon.ico").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/assets/img/favicons/favicon.ico")?;
app.at("/favicon.ico").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/assets/img/favicons/favicon.ico")?;
app.at("/assets/dist/css/bootstrap.min.css").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/assets/dist/css/bootstrap.min.css")?;
app.at("/assets/brand/bootstrap-logo-white.svg").serve_file("/home/davidm/tryredox/tide-rustls/examples/bootstrap-5.1.0-examples/assets/brand/bootstrap-logo-white.svg")?;
println!( r###"Listening at https://{}/hello"### , &addr);
println!( r###"Listening at https://{}/cheatsheet/cheatsheet"### , &addr);
app.listen(TlsListener::build().addrs(addr).cert(cert).key(key)).await?;
Ok(())
}) //end of block_on and async
} //end of main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment